C# 在C语言中实现单例可继承类#

C# 在C语言中实现单例可继承类#,c#,inheritance,singleton,C#,Inheritance,Singleton,我发现在C#中可以实现一个单例类,如下所示: class Singleton { private static Singleton _instance; public static Singleton Instance { get { return _instance ?? (_instance = new Singleton()); } } protected Singleton() { } } 它适用于类型为单例的实例,即: v

我发现在C#中可以实现一个单例类,如下所示:

class Singleton
{

    private static Singleton _instance;

    public static Singleton Instance
    {
        get { return _instance ?? (_instance = new Singleton()); }
    }

    protected Singleton() { }
}
它适用于类型为
单例的实例,即:

var a = Singleton.Instance;
var b = Singleton.Instance;
Console.WriteLine(ReferenceEquals(a, b)); //Prints True.
但是,如果我希望Singleton的派生类也遵循Singleton模式,即:

class A:Singleton
{ ... }
A a = A.Instance;
在这种情况下,静态成员
实例
Singleton
类访问,并创建一个
Singleton
实例,这不是目标。 此外,此解决方案存在两个主要问题:

  • 派生类可以实现自己的构造函数,并失去单例模式
  • 如果存在另一个
    Singleton
    实例,则派生类将引用该派生较少的实例
我的问题是:有没有其他方法来实现C中的单例类#确保派生类也是单例的?

忽略通常的“不要使用单例,看看你的设计。”参数,你可以这样实现一个(假设你的派生类有默认构造函数):

公共抽象类单例,其中T:class,new()
{
私有静态T_实例;
公共静态GetInstance()
{
if(_instance==null)
_实例=新的T();
返回_实例;
}
}
并得出如下结论:

public class SingletonA : Singleton<SingletonA> { /* .... */ }
public class SingletonB : Singleton<SingletonB> { /* .... */ }
public-class-SingletonA:Singleton{/*../}
公共类SingletonB:Singleton{/*../}
但是,我个人并不提倡这种单一模式。它们确实有其(罕见的)用途,但它们可能更像是一件让人头疼的事——使用美化的全局变量容器

此外,还要注意螺纹安全

我的问题是:是否有其他方法在C#中实现单例类,确保派生类也是单例类

你可以在构造器中进行某种检查:

的实际类型是密封的
  • this
    的实际类型是
    Singleton
  • 没有创建该类型的其他实例(通过保留
    哈希集
  • 然而,这似乎毫无意义。您的基类实际上想要实现什么

    单例模式是(顺便说一句,您的示例没有,它不是线程安全的),那么为什么要使用基类呢?基类本身不是一个单例(可能会有很多实例——每个子类一个实例),那么有什么好处呢

    在我看来,“对于对象的实际类型,我是一个单例对象”并不是一个合适的继承基础,坦率地说,无论如何,我都会尽量避免单例模式


    如果你真的想要一个基类,那应该是因为有一些共同的功能,所有的子类自然继承。这与这些子类是否为单例无关。

    有趣的问题是,我建议对此进行一番解读:我也会谨慎使用实例属性而不是GetInstance()方法。如果在遇到断点时将鼠标悬停在调试器中的Instance属性上,可能会发生一些有趣的事情,这是由于代码中正在构造实例的副作用造成的。当然,a)避免单例模式和b)避免其构造函数中的副作用要好得多。@DanBryant,绝对正确-已编辑。+1 for
    “不要使用单例,看看你的设计。”
    。我有点困惑,你的泛型
    单例
    类要求
    t
    具有公共无参数构造函数,因此,没有一个继承的类实际上被强制为单例。而且
    GetInstance
    方法是非静态的(显然),所以为了调用它,您需要一个实例,应该使用
    GetInstance
    @Moo Juice来获取该实例。好的,修复了这个错误后,只剩下一个问题:您的
    Singleton
    类有一个
    new()
    约束,这意味着
    T
    必须具有公共构造函数。因此,可以简单地使用new创建类,如
    SingletonA:Singleton
    。这不是违背了单身汉的目的吗?至于你的最后一点。。。下面呢?我有一个项目“sProj”,其中一些静态数据存储在一个单例中。有两个主要的项目与之相衔接maxProj'需要整个数据集(单例的属性),而minProj'只需要静态数据的一个子集。既然“maxProj”使用了“minProj”相同的功能,那么为“min”需求定义一个基本单例并从中继承——允许我共享resources@laventnc:仅凭代码描述恐怕很难理解相对复杂的问题。您可能希望在CodeReview上展示您的代码,并在那里请求审阅。
    public class SingletonA : Singleton<SingletonA> { /* .... */ }
    public class SingletonB : Singleton<SingletonB> { /* .... */ }