C# C“单身人士”;GetInstance";方法或;“实例”;财产?

C# C“单身人士”;GetInstance";方法或;“实例”;财产?,c#,singleton,instance,C#,Singleton,Instance,从需要“获取单例类的实例”的API最终用户的角度来看,您更喜欢“获取”一个.instance属性还是“调用”一个.GetInstance()方法 在C#中,我更喜欢.Instance,因为它符合一般准则。视情况而定。您需要传递参数吗?如果是这样,我会使用GetInstance()。如果不是,可能不重要(至少从调用的角度来看,因为它们实际上都是方法;但是,如果您尝试更基于标准,并且在这种情况下,一个实例似乎更好,那么这一点很重要)。我更喜欢属性,这些是标准模式。与所有方法一样,这取决于:) 如果s

从需要“获取单例类的实例”的API最终用户的角度来看,您更喜欢“获取”一个.instance属性还是“调用”一个.GetInstance()方法


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

视情况而定。您需要传递参数吗?如果是这样,我会使用GetInstance()。如果不是,可能不重要(至少从调用的角度来看,因为它们实际上都是方法;但是,如果您尝试更基于标准,并且在这种情况下,一个实例似乎更好,那么这一点很重要)。

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

与所有方法一样,这取决于:)

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


如果我们只是屏蔽以保护singleton实例,则最好使用属性。

如果要创建singleton,则不能在每次
GetInstance
调用或
instance
property 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;
    }
}

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

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

GetInstance()不一定意味着单例实例。因此,我将使用GetInstance()来处理以下情况:实例创建是按需进行的,direct new是不可取的,实例可以是,但不能保证是相同的。对象池也符合这些条件。(事实上,单例是具有状态保留的对象池的特化:-))

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

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

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,以确保在访问实例变量之前完成对实例变量的赋值

@Mickel依赖注入加上单身模式?就我个人而言,我甚至从未为自己的合法身份写过
singleton
,而且我一般都怀疑它的必要性。@silky如果WinForm真的只能作为一个实例跨多个DLL创建/访问,你该怎么办?@silky可以肯定,它们的使用量远远超过了它们应该使用的量-但任何时候我们都必须处理可用资源有限的事实,我们无法避免某种形式的全球化。单例只是一种形式化的强制执行全局的方法。迈克尔·托德:我从来没有写过“真正的”winforms应用程序:)就我自己的经验而言。“获取实例”应该是“获取实例”——
新的
有点误导-p@Marc格雷威尔-同意。这一点说得很好。在写一个单件之前,请三思。我见过这样的情况,他们强迫使用集成测试而不是单元测试——单例访问数据库,其他类与之耦合。当我仔细思考并阅读注释时,.Instance属性实际上意味着只有一个“单个实例存在”。然而.GetInstance()可以解释为“获取实例”,例如工厂。@TrueWill-yes,同意。我在班上工作是为了避开单身汉。我猜原来的问题仍然有效。。。那就是。。。如果您绝对需要一个单例,如果存在这种情况;)你确定吗?起初我也这么想,但是私有构造函数确保只有该类才能创建自身的实例。在任何情况下,您都可以删除您的私有构造函数。@RaYell我认为他的代码示例只是为了演示属性和方法之间的区别。@Ty-如果您删除私有构造函数,那么就有一个隐式的公共构造函数-这不是我们想要的。是的:对于单例,您绝对应该重复使用
实例
(或类似)。私有构造函数只允许类成员创建实例。这就是代码中发生的事情。它会起作用,但不会是单身。每次使用
instance
属性或
GetInstance()
方法时,您都会创建一个新实例。@Rex M-我知道这一点,我已经在上面给出了答案。我只是认为指出示例代码中的一个缺陷是一个好主意,因为它写的应该是singleton。但特别是对于singleton,只有第一次调用才能完成工作。下面的调用应该只返回先前准备好的实例。@当然,但是在延迟加载的单例中,调用方不知道它是否已被实例化,因此每个调用都可能是重调用。很好的双重检查锁。但是,如果您只需要实例化您的单例,请使用:private static readonly singleton uniqueInstance=new singleton();
                if (uniqueInstance == null)
                {
                    uniqueInstance = new Singleton();
                }