【问题标题】:What's the correct way to have Singleton class in c# [duplicate]在c#中拥有Singleton类的正确方法是什么[重复]
【发布时间】:2018-09-05 20:53:03
【问题描述】:

我正在学习C#中的Singleton设计模式,我已经用两种方式编写了下面的代码,我想知道哪种方式是创建Singleton类的正确方法:

public sealed class TranslationHelper
{
    // first way
    private static readonly TranslationHelper translationHelper = new TranslationHelper();
    // second way
    public static readonly TranslationHelper translationHelpers = new TranslationHelper(); // Direct call

    public static TranslationHelper GetTranslationHelper()
    {
        return translationHelper;
    }

    private TranslationHelper()
    {
    }
}

打电话:

TranslationHelper instance = TranslationHelper.GetTranslationHelper();
TranslationHelper ins = TranslationHelper.translationHelpers;

我是初学者,所以我不确定这两种方法是否相同。请指导我。

【问题讨论】:

  • 有史以来最好的指南,作者是@JonSkeet:csharpindepth.com/Articles/General/Singleton.aspx。读完你就会明白两者都是错误的
  • 区别(除了名称)在publicprivate 之间。通常,您几乎从不想拥有public 字段——您应该改用public property。至于单例题,其他cmet有设计模式的资源。
  • @JoeSewell:感谢您的意见,请您也添加一行解释。
  • @CamiloTerevinto 现在你让我好奇了。在静态构造函数中初始化也是错误的吗?静态构造函数仅在使用类时调用,.net 保证它只运行一次。 (即线程安全)

标签: c# .net design-patterns


【解决方案1】:

如果您使用的是 .Net 4 或更高版本,您可以像这样使用 Lazy<T> 类型:

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
}

通过将此设计模式与私有构造函数一起使用,您可以确保类及其仅在使用时创建。这是确保的,因为

  1. 它只能被自己调用,所以它不会被提前实例化。
  2. Lazy&lt;T&gt; 关键字与 private static readonly lambda 函数一起使用时,现在提供了一种视觉上清晰的方式,可以从函数本身中懒惰地创建类的实例。
  3. public Singleton Instance 属性提供了一种从类外部访问该单例的方法。

【讨论】:

  • 我不知道为什么我投了反对票,因为这是从 .Net 4 开始创建单例类的正确答案。
  • Lazy 给了你什么是你没有它就没有的?
  • Lazy 为您提供延迟实例化,直到您实际引用实例属性,同时保持线程安全,否则您需要自己管理。
  • 正确,感谢@adam-g 的补充。
猜你喜欢
  • 2014-05-31
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 1970-01-01
  • 2016-07-04
  • 2020-06-15
  • 1970-01-01
  • 2010-09-15
相关资源
最近更新 更多