Stopwatch exception implementation in C#
You have the beginning of a stopwatch representation—you have its data. You still need to add its behavior.

Approach your design of the class as if the class should stand on its own. Input/output will be handled by something else, like the console, but the stopwatch should be the authority on its internal state.

The simplest stopwatch has a start/stop button and a display. We'll interpret "having a display" to mean "a way to get the stored elapsed time".

This means we'll need to provide three methods:


Start: Sets the stopwatch in a running state.
Stop: Sets the stopwatch in an idle state.
TimeElapsed: Reads out the currently elapsed time.


Additionally, Start and Stop have the requirement that they should throw InvalidOperationException when the stopwatch is not a compatible state. Our stopwatch will need a notion of running to do this.

Let's look how we can modify the stopwatch class to adopt this behavior. I've annotated some below:

    public class Stopwatch
    {
        private DateTime _startTime; // we need this
        private DateTime _stopTime; // ? either this or duration
        private TimeSpan _duration;
        public DateTime StartTime() // why do we return a value here?

        {
            // we still need to check whether we are already running
            _startTime = DateTime.Now;
            return _startTime;
        }

        public DateTime Stoptime() // why do we return a value here?

        {
            // we still need to check whether we are still running
            _stopTime = DateTime.Now;
            return _stopTime;
        }

        // We still need the notion of 'currently running'
    }

    // First attempt
    public class Stopwatch
    {
        private DateTime _startTime;
        private DateTime _stopTime;
        private Boolean _running;

        public void StartTime()
        {
            if ( _running )
            {
                throw new InvalidOperationException("Cannot start: already running");
            }
            _startTime = DateTime.Now;
            _running = true;
        }

        public void Stoptime()
        {
            if ( !_running )
            {
                throw new InvalidOperationException("Cannot stop: not running");
            }

            _stopTime = DateTime.Now;
            _running = false;
        }

        public TimeSpan ElapsedTime()
        {
            if ( _running )
            {
                return DateTime.Now - _startTime;
            }
            else
            {
                return _stopTime - _startTime;
            }
        }
    }


Note that we check if the stopwatch is currently running when asking for elapsed time: otherwise, we're going to get a very strange reading.

Now we can 'clean up' a little bit to follow conventions:


Class members are implicitly private, so we don't need to add the private modifier.
Members should start with a capital letter.


Which gives us:

    public class Stopwatch
    {
        DateTime StartTime;
        Boolean IsRunning;
        DateTime StopTime;

        public void Start()
        {
            if (IsRunning)
            {
                throw new InvalidOperationException("Cannot start: already running");
            }
            StartTime = DateTime.Now;
            IsRunning = true;
        }

        public void Stop()
        {
            if (!IsRunning)
            {
                throw new InvalidOperationException("Cannot stop: not running");
            }
            IsRunning = false;
            StopTime = DateTime.Now;
        }

        public TimeSpan ElaspedTime()
        {
            if (IsRunning)
            {
                return DateTime.Now - StartTime;
            }
            else
            {
                return StopTime - StartTime;
            }
        }
    }


And a quick Main to play around with it:

    static void Main(string[] args)
    {
        var stopwatch = new Stopwatch();
        int choice;

        do
        {
            Console.Write("1-Start Timer\n2-Stop Timer\n3-Read Timer\n0-Quit\n");
            choice = Convert.ToInt32(Console.ReadLine());
            switch (choice)
            {
                case 1: stopwatch.Start(); break;
                case 2: stopwatch.Stop(); break;
                case 3: Console.WriteLine(stopwatch.ElaspedTime()); break;
            }
        } while (choice != 0);
    }