C# 返回子体的单例实例

C# 返回子体的单例实例,c#,inheritance,static,singleton,C#,Inheritance,Static,Singleton,我有几个类是单例的,所以我尝试用方法GetInstance(params)和派生类创建一个父基类,它应该实现这个方法并返回自己的实例(所以我不必强制转换它们)。。。由于它们是单例,所以方法应该是静态的,但不允许重写静态方法。编写代码的最佳方法是什么?我想要的示例代码: public class Base { public static virtual T GetInstance<T>() where T : class; } public class Der

我有几个类是单例的,所以我尝试用方法GetInstance(params)和派生类创建一个父基类,它应该实现这个方法并返回自己的实例(所以我不必强制转换它们)。。。由于它们是单例,所以方法应该是静态的,但不允许重写静态方法。编写代码的最佳方法是什么?我想要的示例代码:

  public class Base {

    public static virtual T GetInstance<T>() where T : class;
  }


  public class Derived {
    Derived instance;

    public static override T GetInstance<T>() where T : typeOf(this){
      if (instance == null) {
        instance = new Derived();
        }
      return instance;
    }
  }
不是

我知道这不好,我也缺乏T型的经验,所以欢迎任何建议。 谢谢

编辑:

public class Base {
    static Dictionary<Type, Object> _Singletones = new Dictionary<Type, Object>();
    public static T GetInstance<T>() where T : class {
        Type t = typeof(T);
        if (_Singletones.ContainsKey(t))
             return _Singletones[t] as T;
        else {
            // Create instance by calling private constructor and return it
            T result = Activator.CreateInstance(t, true) as T;
            _Singletones.Add(t, result);
            return result;
        }
    }
}

或者,如果可以以某种方式在Base中定义GetInstance()方法,那么派生类不需要遍历它,但它将返回调用它的类的实例。。。GetInstance()将返回派生的实例

尝试抽象工厂设计模式。也许其他的也适合

您需要在工厂级别强制执行“单例性”,然后调用可能如下所示:

FooFactory.GetBarInstance().SomeDerivedMethod();

为什么不简单地将方法声明为非泛型并直接使用派生类型:

public class Derived {
  Derived instance;

  public static Derived GetInstance() {
    if (instance == null) {
      instance = new Derived();
    }
    return instance;
  }
}

这不是一个真正的答案,但不管怎样,知道这一点可能很好

你可以用
字典
写单音。下面的方法要求每种类型都实现私有构造函数。当然,如果singletones字典中已经有一个类的实例,那么您也可以检查每个派生类。这甚至可以避免有人使用
Activator
创建实例

未测试:

public class Base {
    static Dictionary<Type, Object> _Singletones = new Dictionary<Type, Object>();
    public static T GetInstance<T>() where T : class {
        Type t = typeof(T);
        if (_Singletones.ContainsKey(t))
             return _Singletones[t] as T;
        else {
            // Create instance by calling private constructor and return it
            T result = Activator.CreateInstance(t, true) as T;
            _Singletones.Add(t, result);
            return result;
        }
    }
}
公共类基{
静态字典_Singletones=新字典();
公共静态T GetInstance(),其中T:class{
类型t=类型(t);
if(_Singletones.ContainsKey(t))
将_Singletones[t]返回为t;
否则{
//通过调用私有构造函数创建实例并返回它
T result=Activator.CreateInstance(T,true)作为T;
_单音。添加(t,结果);
返回结果;
}
}
}

是的,这是一种方式。我想强制任何派生类通过父基实现singleton方法GetInstance()。你不能强制在C中实现静态方法35;是的,我知道,这就是为什么我征求建议,如果有可能实现我想要的:)@Zavael-这取决于你。教科书中使用静态方法实现单例是不可能的。但是,一个更好的实施单例性的方法是使用IoC,并让容器管理实例的生命周期。在大多数框架中,声明给定类的所有子类都有单例生存期应该很简单。这是可以的,尽管这样的静态方法应该是线程安全的!差不多了。。。但是,我如何不是从参数而是从调用类获取类型,所以我应该调用Base.GetInstance()=Derived.GetInstance(),而不是Base.GetInstance(),它返回Base和Derived.get。。返回Derived@Groo您是对的,但是当您有性能关键的代码时(例如,多次访问该方法时),这可能会很糟糕。也许使用两个字典(交换)可以提高性能。@Zavael我认为这是不可能的。您需要使用
Base.GetInstance()
访问它。(在dervied类工作时没有基础)@Felix:不知道你说的交换是什么意思。如果需要从不同的线程访问它,那么它应该是线程安全的,除非所有可能的值在启动时都被实例化,并且字典是只读的(现在没有任何东西强制它)。这个类应该有什么用途?IoC容器可能更合适。我将有更多的单例,因此我想用这样的方式来创建实例,即来自父级的静态继承方法始终可以从调用它的位置返回类型的实例(即使它来自子代)这里有类似的讨论,似乎没有办法强迫后代成为单身,似乎我想要一些奇怪的东西(@Zavael:这就是为什么它被称为抽象。如果你需要一个Foo,你可以使用FooFactory。它可以实现一个通用接口,但每个工厂都实例化自己的类型。+1感谢lazysingleton1双重检查:)lambda版本我不能使用,因为我没有一个实例,而是一个单例字典
public class Base {
    static Dictionary<Type, Object> _Singletones = new Dictionary<Type, Object>();
    public static T GetInstance<T>() where T : class {
        Type t = typeof(T);
        if (_Singletones.ContainsKey(t))
             return _Singletones[t] as T;
        else {
            // Create instance by calling private constructor and return it
            T result = Activator.CreateInstance(t, true) as T;
            _Singletones.Add(t, result);
            return result;
        }
    }
}