我想要一个在程序启动时自动实例化的单例。
我所说的“自动实例化”是指 Singleton 中的代码应该在程序启动时实例化自身,而无需其他代码进行任何调用或声明。
所以我想要像下面这样的东西在程序启动时实例化并写出“MySingleton Instantiated”(主代码不做任何事情)......
static class MySingleton
{
private static MySingleton self = new MySingleton();
protected MySingleton()
{
System.Console.WriteLine("MySingleton Instantiated");
}
}
除非这不起作用,因为 C# 只会在需要时初始化类的静态成员,即当它们被访问时/等等。
那我该怎么办?这可以做到吗?
我个人没有使用 C++ 完成此操作(有一段时间没有使用 C++),但我很确定它可以用 C++ 完成,但不确定 C#。
感谢任何帮助。谢谢。
我实际上想用它做的是...... 会有许多这样的单例类(随着时间的推移可以添加更多),所有这些单例类都将继承自一个公共(public)(抽象)父类(又名 PClass)。
PClass 将有一个静态成员,它是 PClasses 的集合...和一个将自身添加到集合中的构造函数...
然后理论上所有的单例都将自动添加到集合中(因为当它们被实例化时,基础 PClass 构造函数被调用并将新对象添加到集合中)......然后可以在不知道任何事情的情况下使用集合已经实现了哪些子(单例)类,并且可以随时添加新的子(单例)类,而无需更改任何其他代码。
不幸的是,我无法让 child (单例)实例化自己...搞砸了我的小计划,导致了这篇文章。
希望我解释得足够好。
附言。是的,我知道对单例及其使用有不好的感觉……但它们有时很有用,即使撒旦自己制作了单例,我仍然想知道我的问题是否可以在 C# 中解决。衷心感谢大家。
最佳答案
Chris 提到的 IoC 方法可能是最好的,但如果失败,我能想到的“最佳”解决方案是按照以下方式使用反射和属性做一些时髦的事情:
public class InitOnLoad : Attribute
{
public static void Initialise()
{
// get a list of types which are marked with the InitOnLoad attribute
var types =
from t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes())
where t.GetCustomAttributes(typeof(InitOnLoad), false).Count() > 0
select t;
// process each type to force initialise it
foreach (var type in types)
{
// try to find a static field which is of the same type as the declaring class
var field = type.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Where(f => f.FieldType == type).FirstOrDefault();
// evaluate the static field if found
if (field != null) field.GetValue(null);
}
}
}
[InitOnLoad]
public class Foo
{
public static Foo x = new Foo();
private Foo()
{
Console.WriteLine("Foo is automatically initialised");
}
}
public class Bar
{
public static Bar x = new Bar();
private Bar()
{
Console.WriteLine("Bar is only initialised as required");
}
}
将对 InitOnLoad.Initialise() 的调用添加到您的主方法中。
您可以取消该属性,但这可能会导致不必要的类型被初始化并不必要地消耗内存(例如上面代码中的 Bar)。
同样值得注意的是,这不会处理动态加载的任何程序集中包含的类型,除非您再次调用 Initialise,但根据您的问题(“程序启动时自动实例化”)听起来并不就像你的问题。
关于c# - 如何 : Auto Instantiate Singleton in C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/795402/