Mar*_*ann 12 .net c# static abstract-class unit-testing
任何人都可以帮我解释如何TimeProvider.Current在下面的类中变为null?
public abstract class TimeProvider
{
private static TimeProvider current =
DefaultTimeProvider.Instance;
public static TimeProvider Current
{
get { return TimeProvider.current; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
TimeProvider.current = value;
}
}
public abstract DateTime UtcNow { get; }
public static void ResetToDefault()
{
TimeProvider.current = DefaultTimeProvider.Instance;
}
}
Run Code Online (Sandbox Code Playgroud)
意见
TimeProvider.Current为null(抛出NullReferenceException).TimeProvider.Current.FWIW,这里也是DefaultTimeProvider类:
public class DefaultTimeProvider : TimeProvider
{
private readonly static DefaultTimeProvider instance =
new DefaultTimeProvider();
private DefaultTimeProvider() { }
public override DateTime UtcNow
{
get { return DateTime.UtcNow; }
}
public static DefaultTimeProvider Instance
{
get { return DefaultTimeProvider.instance; }
}
}
Run Code Online (Sandbox Code Playgroud)
我怀疑是有一些微妙的关系与静态初始化在运行时实际上是允许访问回事TimeProvider.Current所有静态初始化完成之前,但我不能完全把我的手指上.
任何帮助表示赞赏.
FWIW我刚刚扔了
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Run Code Online (Sandbox Code Playgroud)
在getter中,它始终为测试运行中的所有测试用例报告相同的ID,因此问题似乎与线程无关.
仅基于此代码,Current可以null基于它被设置为null.这显然对你没有帮助.
你能提供测试代码吗?如果存在测试相互依赖性,那么对于读者来说,提供任何反馈都会有所帮助.
与此同时,Jon Skeet关于单身人士的文章可能会有所帮助,因为DefaultTimeProvider它实际上是一个单身人士:http://csharpindepth.com/Articles/General/Singleton.aspx
由于Peter Ritchie提供的链接,我可能会对此有部分答案,尽管我无法完全解释正在发生的事情.似乎在TimeProvider的静态启动和DefaultTimeProvider之间存在某种竞争.它可能与beforefieldinit有关.
改变实施似乎已经解决了这个问题.如果没有,它肯定使比赛条件变得更加罕见,到了我尚未看到它的程度.
我将TimeProvider的初始化更改为:
public abstract class TimeProvider
{
private static TimeProvider current;
static TimeProvider()
{
TimeProvider.current = new DefaultTimeProvider();
}
//...
}
Run Code Online (Sandbox Code Playgroud)
而DefaultTimeProvider就是这样的:
public class DefaultTimeProvider : TimeProvider
{
public override DateTime UtcNow
{
get { return DateTime.UtcNow; }
}
}
Run Code Online (Sandbox Code Playgroud)
现在只有一个静态初始化程序(TimeProvider),因为它是一个显式的静态构造函数,所以该类在beforefieldinit之前没有标记.
这似乎已经成功了......
| 归档时间: |
|
| 查看次数: |
1726 次 |
| 最近记录: |