什么是在创建静态实例为单例,这些方式的区别是什么?是在、静态、实例、区别

2023-09-03 09:24:09 作者:独孤求败

我有一个bug最近,只有表现出来,当库建成一个发布版本,而不是调试版本。图书馆是一个.NET的DLL与COM包装,我使用的CoCreateInstance在非托管C ++应用程序创建DLL的类。当我终于跟踪的错误下来它是通过访问一个单独的对象引起的。我有一个实例声明如下所示:

I have had a bug recently that only manifested itself when the library was built as a release build rather than a debug build. The library is a .NET dll with a COM wrapper and I am using CoCreateInstance to create a class from the dll in an unmanaged c++ app. When I finally tracked the bug down it was caused by accessing a singleton object. I had the singleton instance declared like so:

private static readonly MyObjectType s_instance = new MyObjectType;

,然后访问它:

and then accessed it with:

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

固定的问题。任何想法,为什么在初次使用没有工作,如果有任何缺点做无论采用哪种方式?

fixed the issue. Any ideas why the initial usage didn't work and if there are any downsides to doing it either way?

释放的dll似乎是从另一个托管的应用程序非常有用的。

The release dll seemed to be perfectly usable from another managed app.

推荐答案

尝试添加的(空的)静态构造函数或初始化单的在的静态构造函数。

Try adding an (empty) static constructor, or initialize the singleton in a static constructor.

乔恩斯基特具有单模式的充分讨论这里。我不知道为什么会失败,但猜测这可能涉及到beforefieldinit标志。见他的第4个例子,在那里,他增加了一个静态构造函数来调整这个标志。我并不声称自己是beforefieldinit的专家,但这种症状似乎适合一些症状讨论这里

Jon Skeet has a full discussion of singleton patterns here. I'm not sure why it failed, but at a guess it could relate to the "beforefieldinit" flag. See his 4th example, where he adds a static constructor to tweak this flag. I don't claim to be an expert on beforefieldinit, but this symptom seems to fit some of the symptoms discussed here.