Implement Stopwatch.ToString() (#87812)
authorEric Mutta <eric.mutta@gmail.com>
Thu, 22 Jun 2023 11:52:48 +0000 (14:52 +0300)
committerGitHub <noreply@github.com>
Thu, 22 Jun 2023 11:52:48 +0000 (07:52 -0400)
* Implement Stopwatch.ToString()

For the tests, I added a few one-liners to the existing tests
where the Stopwatch.Elapsed property was easy to check.
I also added the OverridesToString() test to check for cases
where the ToString() method is called implicitly. This confirms
that people can write "Console.WriteLine(sw)" where "sw" is
an instance of the Stopwatch class, and get the elapsed time
printed.

Fix #87449

* Fix typo in Stopwatch.cs

Fix typo in the comment within the OverridesToString() test.

* Add XML docs for the ToString() method.

The <returns> tag is somewhat redundant since the <summary> tag
adequately describes what's going on here, but since the convention
is to have both tags, I have used the <returns> tag to clarify that
the returned string renders the elapsed time using the same format as
TimeSpan.ToString().

* Add ToString() override for Stopwatch class.

See https://github.com/dotnet/runtime/pull/87812#discussion_r1235940302

---------

Co-authored-by: Eric Mutta <ericm@creditregistry.com>
src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs
src/libraries/System.Runtime.Extensions/tests/System/Diagnostics/Stopwatch.cs
src/libraries/System.Runtime/ref/System.Runtime.cs

index d6212cd..8c27526 100644 (file)
@@ -89,6 +89,14 @@ namespace System.Diagnostics
             _isRunning = true;
         }
 
+        /// <summary>
+        /// Returns the <see cref="Elapsed"/> time as a string.
+        /// </summary>
+        /// <returns>
+        /// Elapsed time string in the same format used by <see cref="TimeSpan.ToString()"/>.
+        /// </returns>
+        public override string ToString() => Elapsed.ToString();
+
         public bool IsRunning
         {
             get { return _isRunning; }
index 3ddb805..d50906d 100644 (file)
@@ -29,6 +29,7 @@ namespace System.Diagnostics.Tests
             Stopwatch watch = new Stopwatch();
             Assert.False(watch.IsRunning);
             Assert.Equal(TimeSpan.Zero, watch.Elapsed);
+            Assert.Equal(TimeSpan.Zero.ToString(), watch.ToString());
             Assert.Equal(0, watch.ElapsedTicks);
             Assert.Equal(0, watch.ElapsedMilliseconds);
             watch.Start();
@@ -38,6 +39,7 @@ namespace System.Diagnostics.Tests
 
             watch.Stop();
             Assert.False(watch.IsRunning);
+            Assert.Equal(watch.Elapsed.ToString(), watch.ToString());
 
             var e1 = watch.Elapsed;
             Sleep(s_defaultSleepTimeMs);
@@ -64,6 +66,7 @@ namespace System.Diagnostics.Tests
             watch.Reset();
             Assert.False(watch.IsRunning);
             Assert.Equal(TimeSpan.Zero, watch.Elapsed);
+            Assert.Equal(TimeSpan.Zero.ToString(), watch.ToString());
             Assert.Equal(0, watch.ElapsedTicks);
             Assert.Equal(0, watch.ElapsedMilliseconds);
         }
@@ -96,6 +99,25 @@ namespace System.Diagnostics.Tests
             }
         }
 
+        [Fact]
+        public static void OverridesToString()
+        {
+            // In this test we use string interpolation with a Stopwatch instance to trigger
+            // a call to the overridden ToString() method which should return the elapsed time
+            // as a string.
+
+            Stopwatch watch = new Stopwatch();
+            Assert.Equal(TimeSpan.Zero, watch.Elapsed);
+            Assert.Equal($"Elapsed = {watch.Elapsed}", $"Elapsed = {watch}");
+
+            watch.Start();
+            Sleep(s_defaultSleepTimeMs);
+            watch.Stop();
+
+            Assert.True(watch.Elapsed > TimeSpan.Zero);
+            Assert.Equal($"Elapsed = {watch.Elapsed}", $"Elapsed = {watch}");
+        }
+
         [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDebuggerTypeProxyAttributeSupported))]
         public static void DebuggerAttributesValid()
         {
index 09c4ad4..d0b807e 100644 (file)
@@ -8197,6 +8197,7 @@ namespace System.Diagnostics
         public void Start() { }
         public static System.Diagnostics.Stopwatch StartNew() { throw null; }
         public void Stop() { }
+        public override string ToString() { throw null; }
     }
     public sealed partial class UnreachableException : System.Exception
     {