C#Singleton“GetInstance”方法或“实例”属性?

时间:2009-09-01 04:10:06

标签: c# singleton instance

从需要“获取 Singleton类的实例”的API最终用户的角度来看,您更喜欢“获取”。实例属性或“调用”.GetInstance()方法?

public class Bar
{
    private Bar() { }

    // Do you prefer a Property?
    public static Bar Instance
    {
        get
        {
            return new Bar();
        }
    }

    // or, a Method?
    public static Bar GetInstance()
    {
        return new Bar();
    }
}

7 个答案:

答案 0 :(得分:15)

在C#中,我更倾向于.Instance,因为它符合一般准则。

答案 1 :(得分:13)

如果你想创建单身,你不能只在每个GetInstance调用或Instance属性getter上返回新对象。你应该这样做:

public sealed class Bar
{
    private Bar() { }

    // this will be initialized only once
    private static Bar instance = new Bar();

    // Do you prefer a Property?
    public static Bar Instance
    {
        get
        {
            return instance;
        }
    }

    // or, a Method?
    public static Bar GetInstance()
    {
        return instance;
    }
}

选择哪种方式并不重要。如果您更喜欢使用属性选择它,如果您更喜欢方法,它也可以。

答案 2 :(得分:4)

与几乎所有事情一样,这取决于:)

如果单例是延迟加载的并且表示实例化的工作量不仅仅是一小部分,那么GetInstance()更合适,因为方法调用表明正在完成工作。

如果我们只是掩盖以保护单例实例,则首选属性。

答案 3 :(得分:3)

取决于。你需要传递参数吗?如果是这样,我会做GetInstance()。如果没有,可能无关紧要(至少从主张的角度来看,因为它们无论如何都是真正的方法;但是,如果你想要更加基于标准,确实很重要,在这种情况下,实例看起来更好)。

答案 4 :(得分:2)

public class Singleton
{

    private volatile static Singleton uniqueInstance;
    private static readonly object padlock = new object();

    private Singleton() { }

    public static Singleton getInstance()
    {
        if (uniqueInstance == null)
        {
            lock (padlock)
            {
                if (uniqueInstance == null)
                {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

在上面的代码中,实现了双重检查,首先检查是否创建了一个实例,是否已经建立了锁定。一旦在这个块中

                if (uniqueInstance == null)
                {
                    uniqueInstance = new Singleton();
                }

如果实例为null,则创建它。

此外,uniqueInstance变量被声明为volatile,以确保在访问实例变量之前完成对实例变量的赋值。

答案 5 :(得分:0)

我更喜欢属性,这些是标准模式。

答案 6 :(得分:0)

正如@Rex所说,这取决于你想传达的语义。

GetInstance()不一定意味着单例实例。因此,在实例创建按需发生的情况下,我会使用GetInstance(),不希望直接new,并且实例可能是,但不保证是相同的。对象池也符合这些标准。 (实际上,单例是具有状态保留的对象池的特化: - ))

另一方面,

静态实例属性意味着单例和保留的实例标识。

顺便说一句,因为@RaYell提到你的示例代码不是单例,所以你不应该使用Instance属性。在这种情况下,您仍然可以使用GetInstance()方法,因为它将用作实例工厂。