C# 为什么当我访问初始化的静态属性时它会为null?
我有以下代码(从真实代码中提取) 是否可能存在针对静态初始化的竞争条件 到目前为止,进行MCVE的尝试均未成功。下面的规范测试了我的最小可邮寄代码和真实代码。MCVE一个通过了:(而真正的一个失败了。我缺少一些背景,需要进一步的工作来隔离这个问题C# 为什么当我访问初始化的静态属性时它会为null?,c#,C#,我有以下代码(从真实代码中提取) 是否可能存在针对静态初始化的竞争条件 到目前为止,进行MCVE的尝试均未成功。下面的规范测试了我的最小可邮寄代码和真实代码。MCVE一个通过了:(而真正的一个失败了。我缺少一些背景,需要进一步的工作来隔离这个问题 public class Tester { public static class AssemblyLoggerMCVE { public static Lazy<Window> Window { get;
public class Tester
{
public static class AssemblyLoggerMCVE
{
public static Lazy<Window> Window { get; } = new Lazy<Window>(NewWindowHandler);
private static Window NewWindowHandler() => new Window();
public static IScheduler Scheduler =>
new DispatcherScheduler(Window.Value.Dispatcher);
}
/// This passes
[StaFact]
public void AssemblyLoggerMCVEShouldWork()
{
AssemblyLoggerMCVE.Scheduler.Should().NotBeNull();
}
/// This fails
[StaFact]
public void AssemblyLoggerShouldWork()
{
AssemblyLogger.Scheduler.Should().NotBeNull();
}
}
公共类测试器
{
公共静态类AssemblyLoggerMCVE
{
公共静态惰性窗口{get;}=new Lazy(NewWindowHandler);
私有静态窗口NewWindowHandler()=>新窗口();
公共静态ISScheduler调度程序=>
新的调度程序(Window.Value.Dispatcher);
}
///这过去了
[统计数字]
public void AssemblyLoggerMCVEShouldWork()
{
AssemblyLoggerMCVE.Scheduler.Should().NotBeNull();
}
///这失败了
[统计数字]
公共无效程序集LoggerShouldWork()
{
AssemblyLogger.Scheduler.Should().NotBeNull();
}
}
下面的测试用例可以清楚地复制错误,它的上下文比所建议的问题所需的上下文更多
public class Tester
{
public class AssemblyLoggerControlModel
{
public static IScheduler S = AssemblyLoggerMCVE.Scheduler;
}
public class AssemblyLogger
{
public static AssemblyLoggerControlModel ModelInstance { get; } =
new AssemblyLoggerControlModel();
public static readonly Lazy<Window> Window =
new Lazy<Window>(NewWindowHandler);
private static Window NewWindowHandler() => new Window();
public static IScheduler Scheduler =>
new DispatcherScheduler(Window.Value.Dispatcher);
}
}
公共类测试器
{
公共类AssemblyLoggerControlModel
{
公共静态isScheduler S=AssemblyLoggerMCVE.Scheduler;
}
公共类汇编记录器
{
公共静态AssemblyLoggerControlModelInstance{get;}=
新的AssemblyLoggerControlModel();
公共静态只读惰性窗口=
新的Lazy(NewWindowHandler);
私有静态窗口NewWindowHandler()=>新窗口();
公共静态ISScheduler调度程序=>
新的调度程序(Window.Value.Dispatcher);
}
}
静态初始值设定项之间存在循环依赖关系。静态属性的静态初始化AssemblyLogger.ModelInstance
导致初始化静态属性AssemblyLoggerControlModel.S
,然后尝试调用静态AssemblyLogger.Scheduler
方法,该方法反过来尝试o由于AssemblyLogger的静态初始化未完成而访问的窗口
仍然为空
基本上,我的代码是纯粹的邪恶,最好的做法是
你试过使用老式的getter吗?这看起来像一个bug。Photoshop。除非你表现出来。你能尝试在你的示例中添加一个空的
静态构造函数,看看它是否能工作吗?我建议你花些时间在MCVE上。显然,这在正常情况下是不会发生的。而且你没有发布足够的代码来支持它想想原因吧。我对答案很好奇,但问题很难说:“这是我项目中的一个切入点,请猜猜为什么它不该怎么做”。我发现了问题。我会在答案中复制错误并发布它。这是我的错,但是错误是微妙的。
public class Tester
{
public static class AssemblyLoggerMCVE
{
public static Lazy<Window> Window { get; } = new Lazy<Window>(NewWindowHandler);
private static Window NewWindowHandler() => new Window();
public static IScheduler Scheduler =>
new DispatcherScheduler(Window.Value.Dispatcher);
}
/// This passes
[StaFact]
public void AssemblyLoggerMCVEShouldWork()
{
AssemblyLoggerMCVE.Scheduler.Should().NotBeNull();
}
/// This fails
[StaFact]
public void AssemblyLoggerShouldWork()
{
AssemblyLogger.Scheduler.Should().NotBeNull();
}
}
public class Tester
{
public class AssemblyLoggerControlModel
{
public static IScheduler S = AssemblyLoggerMCVE.Scheduler;
}
public class AssemblyLogger
{
public static AssemblyLoggerControlModel ModelInstance { get; } =
new AssemblyLoggerControlModel();
public static readonly Lazy<Window> Window =
new Lazy<Window>(NewWindowHandler);
private static Window NewWindowHandler() => new Window();
public static IScheduler Scheduler =>
new DispatcherScheduler(Window.Value.Dispatcher);
}
}