我今天遇到了一个问题,一位朋友建议我使用全局静态实例或更优雅地使用单例模式。我花了几个小时阅读单身人士,但有些事情仍然让我感到厌烦。
背景: 我想要完成的是创建一个API的实例并在我的所有类中使用这个实例(而不是建立新的连接等)。
似乎有大约100种创建单例的方法,但在yoda的帮助下,我发现了一些线程安全的例子。 ..还给出了以下代码:
public sealed class Singleton
{
public static Singleton Instance { get; private set; }
private Singleton()
{
APIClass api = new APIClass(); //Can this be done?
}
static Singleton() { Instance = new Singleton(); }
}
如何/在哪里实例化这个新类以及如何从一个单独的类中调用它?
编辑: 我意识到Singleton类可以用类似
的方式调用Singleton obj1 = Singleton.Instance();
但是我能够访问API类中的方法(即obj1.Start)吗? (不是我需要,只是问)
编辑#2:我可能在检查答案时有点过早,但我确实有一件小问题仍在引起我的问题。 API启动很好,遗憾的是我能够启动两个实例吗?新代码
public sealed class SingletonAPI
{
public static SingletonAPI Instance { get; private set; }
private SingletonAPI() {}
static SingletonAPI() { Instance = new SingletonAPI(); }
// API method:
public void Start() { API myAPI = new API();}
}
但如果我尝试做这样的事情......
SingletonAPI api = SingletonAPI.Instance;
api.Start();
SingletonAPI api2 = SingletonAPI.Instance; // This was just for testing.
api2.Start();
我收到错误消息,说我无法启动多个实例。
答案 0 :(得分:9)
为什么不直接向您的单身人士添加公共APIClass属性?
public sealed class Singleton
{
public static Singleton Instance { get; private set; }
private APIClass _APIClass;
private Singleton()
{
_APIClass = new APIClass();
}
public APIClass API { get { return _APIClass; } }
static Singleton() { Instance = new Singleton(); }
}
然后您的呼叫网站如下:
Singleton.Instance.API.DoSomething();
或者,如果您是API类的作者,您可以将其设为单身,而不是将其包装在单个类中:
public sealed class SingletonAPI
{
public static SingletonAPI Instance { get; private set; }
private SingletonAPI() {}
static SingletonAPI() { Instance = new SingletonAPI(); }
// API method:
public void DoSomething() { Console.WriteLine("hi"); }
}
API调用:
SingletonAPI.Instance.DoSomething();
答案 1 :(得分:5)
这是official Microsoft approach。
单例的优点在于您可以在代码中的任何位置使用和访问它,而无需创建类的实例。事实上,这是它的存在理由,一个类的单个实例,例如
Singleton.Instance.MyValue 和 Singleton.Instance.DoSomething();
答案 2 :(得分:3)
您不会实例化该类 - 您使用的模式在第一次使用时基本上实例化。您正在使用的方法的优点是它的线程安全(只会实例化一次,无论有多少线程尝试访问它),懒惰(在您尝试访问Singleton类之前不会实例化),并且简单在实施中。
您需要做的就是:
Singleton.Instance.MyMethodOnSingleton();
或者,或者:
Singleton myInstance = Singleton.Instance; // Will always be the same instance...
myInstance.DoSomething();