当我访问它时,为什么我的初始化静态属性为null?

时间:2017-11-07 14:40:17

标签: c#

我有以下代码(从实际代码中提取)

select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where
CONSTRAINT_NAME =<ConstraintName>

---Find the below views to get constraint details in a db select * from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS select * from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS select * from
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE

当我致电public static class AssemblyLogger { public static Lazy<Window> Window { get; } = new Lazy<Window>(NewWindowHandler); public static IScheduler Scheduler => new DispatcherScheduler( Window.Value.Dispatcher ); } 时,我得到Scheduler。使用我看到的调试器停止

enter image description here

据我所知,这应该是不可能的。 NullReferenceException是静态初始化和只读的,因此对它的任何进一步访问都应该只获取并且它永远不应该为空。

我已经针对初始化程序设置了一个断点但它永远不会被命中

enter image description here

我还尝试了一个静态只读字段,仍然是同样的问题

Window

是否可能存在针对静态初始化的竞争条件?

到目前为止

尝试制作MCVE 并不成功。以下规范测试我的最小可用代码和真实代码。 MCVE通过:(而真正的失败。我错过了一些背景,需要进一步的工作来隔离问题。

public static readonly Lazy<Window> Window  = new Lazy<Window>(NewWindowHandler);

1 个答案:

答案 0 :(得分:1)

错误可以通过以下测试用例清楚地复制,该测试用例的上下文比建议的问题更多。

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);

    }


}

静态初始值设定项之间存在循环依赖关系。静态属性AssemblyLogger.ModelInstance的静态初始化会导致静态属性AssemblyLoggerControlModel.S被初始化,然后尝试调用静态AssemblyLogger.Scheduler方法,而后者又尝试访问Window因为静态初始化对于AssemblyLogger未完成仍为空。

基本上我的代码是纯粹的邪恶,最好的办法是

enter image description here