c# - 如何 : Auto Instantiate Singleton in C#

标签 c# singleton

我想要一个在程序启动时自动实例化的单例。

我所说的“自动实例化”是指 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/

相关文章:

c# - 在 Canvas 中添加椭圆位置

c++ - 跨平台代码组织

c# - 如何将图像放入剪贴板?

c# - 在运行时 C# 从不同的命名空间中选择对象?

java - Singleton 实例是在什么上同步的?

c++ Singleton with map 原因 "violation reading location"

java - GWT+Java : Globals, 单例和头痛

.net - .Net 中的单例模式是不可能的吗?

javascript - 父子记录与 HTML 表的关系

c# - 使用 PetaPoco 分页映射关系