I'm new to C# programming and has been following a certain intermediate tutorial that has asked me to write a stopwatch simulation code that includes an exception system:
Exercise 1: Design a Stopwatch
Design a class called Stopwatch. The job of this class is to simulate a stopwatch. It should provide two methods: Start and Stop. We call the start method first, and the stop method next. Then we ask the stopwatch about the duration between start and stop. Duration should be a value in Timespan. Display the duration on the console.
We should also be able to use a stopwatch multiple times. So we may start and stop it and then start and stop it again. Make sure the duration value each time is calculated properly.
We should not be able to start a stopwatch twice in a row (because that may overwrite the initial start time). So the class should throw an InvalidOperationException is it's started twice.
Educational tip: The aim of this exercise is to make you understand that a class should be always in a valid state. We use encapsulation and information hiding to achieve that. The class should not reveal its implementation detail. It only reveals a little bit, like a black box. From the outside, you should not be able to misuse a class because you shouldn't be able to see the implementation detail.
Transcribed from:
I have implemented code that does this exactly, however, I want to learn how to optimize my code to use fewer lines and make it more readable.
using System;
namespace Stopwatch_Training
{
class Program
{
public class Stopwatch
{
private DateTime _startTime;
private DateTime _stopTime;
private TimeSpan _duration;
public DateTime StartTime()
{
_startTime = DateTime.Now;
return _startTime;
}
public DateTime Stoptime()
{
_stopTime = DateTime.Now;
return _stopTime;
}
}
static void Main(string[] args)
{
var stopwatch = new Stopwatch();
int input1;
DateTime starTime;
DateTime endTime;
double duration;
int counter = 0;
while (true)
{
Console.Write("1-Start Timer\n2-Stop Timer\n");
input1 = Convert.ToInt32(Console.ReadLine());
if (input1 == 1)
{
starTime = stopwatch.StartTime();
counter = 1;
}
else
{
throw (new InvalidOperationException("Please Start the timer with 1"));
}
Console.WriteLine("Please enter '2' to stop the timer whenever you want");
input1 = Convert.ToInt32(Console.ReadLine());
if (input1 == 2)
{
endTime = stopwatch.Stoptime();
counter = 0;
}
else
{
throw (new InvalidOperationException("Please end the timer with 2"));
}
if (counter == 1)
{
throw (new InvalidOperationException("stuff"));
}
duration = (endTime - starTime).TotalSeconds;
if (duration > 60.0)
{
duration = (endTime - starTime).TotalMinutes;
Console.WriteLine(duration + "m");
}
else
{
Console.WriteLine(duration + "s");
}
}
}
}
}
System.Diagnostics.Stopwatch
class for inspiration. Specifically itsElapsed
andIsRunning
properties, and the fact that none of its methods write anything to the console: that's not their responsibility, and it would add an unnecessary dependency which makes the class more difficult to reuse. \$\endgroup\$