9

从需要“获取”单例类的实例的 API 最终用户的角度来看您更喜欢“获取” .Instance属性还是“调用” .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();
    }
}
4

7 回答 7

19

在 C# 中,我更喜欢.Instance,因为它符合一般准则。

于 2009-09-01T04:11:57.133 回答
14

如果要创建单例,则不能只在每次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;
    }
}

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

于 2009-09-01T04:17:56.950 回答
4

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

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

如果我们只是通过掩蔽来保护单例实例,那么最好使用属性。

于 2009-09-01T04:14:50.013 回答
3

依靠。需要传递参数吗?如果是这样,我会做 GetInstance()。如果不是,则可能无关紧要(至少从调用的角度来看,因为无论如何它们实际上都是两种方法;但是,如果您尝试更加基于标准,并且在这种情况下会出现一个实例,这确实很重要变得更好)。

于 2009-09-01T04:12:11.390 回答
3
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();
                }

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

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

于 2009-09-01T13:03:39.477 回答
0

我更喜欢财产,这些是标准模式。

于 2009-09-01T04:14:38.140 回答
0

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

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

另一方面,静态实例属性意味着一个单例和保留的实例标识。

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

于 2009-09-01T04:23:33.193 回答