C#单例定义

C#单例定义,c#,singleton,C#,Singleton,我看到的实现是这样的: class MyClass { private static readonly MyClass _instance = new MyClass(); public static MyClass Instance{ get{ return _instance; } } } 为什么不简单一点呢 class MyClass { public static readonly MyClass Instance = new MyCl

我看到的实现是这样的:

class MyClass
{
    private static readonly MyClass _instance = new MyClass();

    public static MyClass Instance{
        get{ return _instance; }
    }
}
为什么不简单一点呢

class MyClass
{
    public static readonly MyClass Instance = new MyClass();
}

你所拥有的一切都会很好,但公共领域通常会因为财产而不受欢迎。您可以更改
get{…}
的实现,而无需更改调用代码。这将使您能够(例如)切换到延迟初始化,其中实例仅在第一次使用时创建

请注意,尽管调用代码不需要更改,但它会更改类的签名,因为只读属性不同于只读字段。

您可以像这样公开公共字段,但我不希望这样。如果将其保留为属性,则可以稍后更改实现。例如,假设您稍后添加了一个静态方法,希望能够在不初始化singleton的情况下调用该方法-使用属性版本,您可以将代码更改为:

public sealed class MyClass
{
    public static MyClass Instance { get { return InstanceHolder.instance; } }

    private MyClass() {}

    private static class InstanceHolder
    {
        internal static readonly MyClass instance = new MyClass();
    }

    public static void Foo()
    {
        // Calling this won't initialize the singleton
    }
}
(对于原始版本,单例可以初始化,也可以不初始化-这取决于CLR。)


这只是一个例子,说明了为什么您可能希望稍后更改实现。对于属性,您可以这样做—对于字段,您不能这样做。

给定代码片段之间的唯一区别是,在第一种情况下,
MyClass
将“按需”实例化。虽然您的示例不包括他的私有和静态构造函数(参见示例4),但为什么?从Java我知道,一旦类以任何方式被使用,首先发生的事情就是静态字段被初始化。在C#中不是一样吗?哦。。。你当然是对的。我误读了第一个示例。是的,但您可以始终将字段更改为属性,而类用户不会注意到它。这样一来,代码一开始就变得简单,只有在需要时才增加复杂性。那不是很好吗?