这不太适合 OPs 场景(我猜他们在 8 年前解决了这个问题),但是如果您只需要为单元测试或其他非生产场景创建秒表,那么您可以使用反射来修改经过的时间。
这不会为您提供最佳性能,并且如果 Stopwatch 的底层实现发生更改可能会中断,因此我会非常谨慎地使用这种方法。
但是,对于需要传递秒表并且无法更改以使用替代实现的单元测试,我发现这种方法运行良好并且风险是可以接受的。
/// <summary>
/// Some static mechanisms for creating Stopwatch instances that start from a specific time.
/// </summary>
public static class TestStopwatch
{
/// <summary>
/// Creates a <see cref="Stopwatch"/> instance with a specified amount of time already elapsed
/// </summary>
/// <param name="start">The <see cref="TimeSpan"/> indicated the elapsed time to start from.</param>
public static Stopwatch WithElapsed(TimeSpan start)
{
var sw = new Stopwatch();
var elapsedProperty = typeof(Stopwatch).GetField("_elapsed", BindingFlags.NonPublic | BindingFlags.Instance);
long rawElapsedTicks = start.Ticks;
if (Stopwatch.IsHighResolution)
{
rawElapsedTicks = (long)((double)rawElapsedTicks / (10000000 / (double)Stopwatch.Frequency));
}
elapsedProperty.SetValue(sw, rawElapsedTicks);
return sw;
}
/// <summary>
/// Initializes a new <see cref="Stopwatch"/> instance, sets the elapsed time property to the specified value,
/// and starts measuring elapsed time.
/// </summary>
/// <param name="start">The <see cref="TimeSpan"/> indicated the elapsed time to start from.</param>
public static Stopwatch StartNew(TimeSpan start)
{
var sw = TestStopwatch.WithElapsed(start);
sw.Start();
return sw;
}
}