Return singleton instances of descendants

2020-03-04 10:00发布

I have a couple of classes that are singletons so I tried to create a parent BaseClass with method GetInstance(params) and derived classes, that should implement this method and return instances of theiselfs (so I dont have to cast them)... as they are singletons the method should be static, but its not allowed to override static methods. What would be the best approach to code it? sample code what i wanted:

  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;
    }
  }

in the code outside of this i want to call

Derived.GetInstance().SomeDerivedMethod()

not

(Derived.GetInstance() as Derived).SomeDerivedMethod() and not
new Derived().getInstance().SomeDerivedMethod()

I know this is not good, and i have lack of experience with the T type too, so any advices are welcomed. thanks

EDIT:

Or if it is possible somehow define the GetInstance() method in Base, so the derived class does not need to ovwerride it, but it will return the instance of class from where it was called... Derived.GetInstance() will return instance of Derived

4条回答
混吃等死
2楼-- · 2020-03-04 10:33

Try the Abstract Factory design pattern. Maybe other creational design patterns may fit too.

You need to enforce the "singleton-ness" on factory level, and then the call may look like:

FooFactory.GetBarInstance().SomeDerivedMethod();
查看更多
欢心
3楼-- · 2020-03-04 10:37

Why not simply declare the method as non-generic and use the derived type directly:

public class Derived {
  Derived instance;

  public static Derived GetInstance() {
    if (instance == null) {
      instance = new Derived();
    }
    return instance;
  }
}
查看更多
Ridiculous、
4楼-- · 2020-03-04 10:41

its not an real answer but maybe its nice to know anyway. Lazy

查看更多
太酷不给撩
5楼-- · 2020-03-04 10:51

You could use a Dictionary<Type, Object> for your singletones. The method below requires each type to implement the constructor private. Of course you could also make a check in each of the derived classes if there is already a instance of the class in the singletones dictionary. This would even avoid somebody to use the Activator to create a instance.

Not tested:

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;
        }
    }
}
查看更多
登录 后发表回答