C#的单例模式

cam*_*cam 15 c# singleton

我需要存储一堆需要全局访问的变量,我想知道单例模式是否适用.从我看过的例子来看,单例模式只是一个无法继承的静态类.但我见过的例子对我的需求来说过于复杂.什么是最简单的单身人士课程?难道我不能只用一些变量制作一个静态的密封类吗?

Jon*_*eet 38

通常,单例不是静态类 - 单例将为您提供类的单个实例.

我不知道你见过的例子,但通常单例模式在C#中可以非常简单:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();
    static Singleton() {} // Make sure it's truly lazy
    private Singleton() {} // Prevent instantiation outside

    public static Singleton Instance { get { return instance; } }
}
Run Code Online (Sandbox Code Playgroud)

这并不困难.

单例相对于静态成员的优点是类可以实现接口等.有时这很有用 - 但有时候,静态成员确实也会这样做.此外,以后通常更容易从单例移动到非单例,例如将单例作为"配置"对象传递给依赖类,而不是那些进行直接静态调用的依赖类.

就个人而言,我会尽量避免使用单身人士 - 除了其他任何事情之外,他们会更加努力地进行测试.它们偶尔会有用.

  • @JonSkeet 我不敢相信 Jon Skeet 回复我:)。谢谢,我去看看 (2认同)

Mor*_*dur 8

有几种模式可能适合你,单身是最糟糕的模式之一.

注册处

struct Data {
  public String ProgramName;
  public String Parameters;
}

class FooRegistry {
  private static Dictionary<String, Data> registry = new Dictionary<String, Data>();
  public static void Register(String key, Data data) {
     FooRegistry.registry[key] = data;
  }
  public static void Get(String key) {
     // Omitted: Check if key exists
     return FooRegistry.registry[key];
  }
}
Run Code Online (Sandbox Code Playgroud)

好处

  • 易于切换到Mock对象进行自动化测试
  • 您仍然可以存储多个实例,但如果需要,您只有一个实例.

缺点

  • 比Singleton或全局变量略慢

静态类

class GlobalStuff {
  public static String ProgramName {get;set;}
  public static String Parameters {get;set;}
  private GlobalStuff() {}
}
Run Code Online (Sandbox Code Playgroud)

好处

  • 简单
  • 快速

缺点

  • 难以动态切换到模拟对象
  • 如果需求发生变化,很难切换到另一种对象类型

简单的单身人士

class DataSingleton {
  private static DataSingleton instance = null;
  private DataSingleton() {}
  public static DataSingleton Instance {
     get {
         if (DataSingleton.instance == null) DataSingleton.instance = new DataSingleton();
         return DataSingleton;
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

好处

  • 没有

缺点

  • 难以创建线程安全单例,如果多个线程访问实例,则上述版本失败.
  • 很难切换模拟对象

我个人喜欢注册表模式,但YMMV.

您应该看一下依赖注入,因为它通常被认为是最佳实践,但这里解释的主题太大了:

依赖注入