Вернуть единичные экземпляры потомков - PullRequest
3 голосов
/ 23 января 2012

У меня есть пара классов, которые являются одиночными, поэтому я попытался создать родительский BaseClass с методом GetInstance (params) и производными классами, которые должны реализовать этот метод и возвращать экземпляры theiselfs (поэтому мне не нужно их приводить). .. поскольку они являются синглетонами, метод должен быть статическим, но его нельзя переопределять статическими методами. Каков был бы лучший подход для его кодирования? пример кода, что я хотел:

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

в коде за пределами этого я хочу позвонить

Derived.GetInstance().SomeDerivedMethod()

не

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

Я знаю, что это нехорошо, и у меня тоже нет опыта работы с T-типом, поэтому любые советы приветствуются. спасибо

EDIT:

Или, если возможно, каким-либо образом определить метод GetInstance () в Base, поэтому производному классу не нужно переопределять его, но он вернет экземпляр класса, из которого он был вызван ... Derived.GetInstance () вернет экземпляр Derived

Ответы [ 4 ]

3 голосов
/ 23 января 2012

Вы можете использовать Dictionary<Type, Object> для своих синглтонов.Приведенный ниже метод требует, чтобы каждый тип реализовывал конструктор private.Конечно, вы можете также проверить в каждом из производных классов, есть ли уже экземпляр класса в словаре одиночных тонов.Это даже не позволит кому-либо использовать 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;
        }
    }
}
3 голосов
/ 23 января 2012

Попробуйте шаблон проектирования Abstract Factory.Может быть, подойдут и другие шаблоны креативного дизайна .

Вам нужно применить «одиночность» на заводском уровне, и тогда вызов может выглядеть следующим образом:

FooFactory.GetBarInstance().SomeDerivedMethod();
2 голосов
/ 23 января 2012

это не реальный ответ, но, возможно, его приятно знать в любом случае. Ленивый

0 голосов
/ 23 января 2012

Почему бы просто не объявить метод как неуниверсальный и напрямую использовать производный тип:

public class Derived {
  Derived instance;

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