.net 什么';这些为单例创建静态实例的方法有什么不同?

.net 什么';这些为单例创建静态实例的方法有什么不同?,.net,com,singleton,.net,Com,Singleton,我最近遇到了一个bug,它只在库构建为发布版本而不是调试版本时才显现出来。该库是一个带有COM包装器的.NET DLL,我使用COCCREATE实例从一个非托管C++应用程序的DLL中创建一个类。当我最终找到这个bug时,它是由访问一个单例对象引起的。我将singleton实例声明为: private static readonly MyObjectType s_instance = new MyObjectType; 然后通过以下方式访问它: public static MyObjectTy

我最近遇到了一个bug,它只在库构建为发布版本而不是调试版本时才显现出来。该库是一个带有COM包装器的.NET DLL,我使用COCCREATE实例从一个非托管C++应用程序的DLL中创建一个类。当我最终找到这个bug时,它是由访问一个单例对象引起的。我将singleton实例声明为:

private static readonly MyObjectType s_instance = new MyObjectType;
然后通过以下方式访问它:

public static MyObjectType Instance 
    { 
        get 
        {                               
            return s_instance; 
        } 
    } 
这是失败的。将其更改为:

private static MyObjectType s_instance;

public static MyObjectType Instance 
    { 
        get 
        {               
            if (s_instance==null) 
            { 
                s_instance = new MyObjectType(); 
            } 
            return s_instance; 
        } 
    } 
修正了这个问题。你知道为什么最初的用法不起作用吗?如果用任何一种方法都有缺点的话

另一个托管应用程序的发布dll似乎完全可用。

尝试添加(空)静态构造函数,或在静态构造函数中初始化单例


Jon Skeet充分讨论了单态模式。我不确定它为什么失败,但我猜测它可能与“beforefieldinit”标志有关。参见他的第四个示例,其中他添加了一个静态构造函数来调整此标志。我并不声称自己是beforefieldinit的专家,但这个症状似乎符合所讨论的一些症状。

只是重复Marc Gravell所说的,但它听起来很像beforefieldinit问题,这意味着空静态构造函数是您的解决方案。您需要发布类中的任何和所有构造函数以获得最终答案


第二种方法具有延迟加载的优点(这是一个优点)。

这个错误是如何表现出来的?它坠毁了吗?是否有错误消息?对CoCreateInstance的调用每次都返回“ClassNotRegistered”。但只有在一个release版本中。在调试构建中,一切正常。是的,这就是为什么我不喜欢更改它。修复程序已升级为只添加一个静态构造函数。这在com中仍然有效,这意味着我可以使实例保持只读,并且仍然是线程安全的。我甚至不知道有静态构造函数这样的东西。谢谢你(不知不觉地)教育我!答对 了添加一个空的静态构造函数修复了这个问题。谢谢不过,在我生命中的两天里,我再也回不去了。事实上,正如我前面所说,添加一个静态构造函数是解决方案。