2012-01-23 2 views
2

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

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() в базе, так что производный класс не должен ovwerride, но он возвращает экземпляр класса, откуда он был вызван ... Derived.GetInstance() вернет экземпляр Derived

+1

Какую цель должны этого класса? Вполне вероятно, что контейнер IoC будет более уместным. – Groo

+0

У меня будет больше синглтонов, поэтому я хотел бы подтянуть логику создания экземпляров таким образом, чтобы статический унаследованный метод от родителя всегда мог возвращать экземпляр типа, из которого он был вызван (даже если он из потомка) – Zavael

+0

здесь аналогичная дискуссия http://www.codeguru.com/forum/showthread.php?t=376943 и похоже, что нет возможности заставить потомка быть одиночными, похоже, что я хотел что-то странное .. :( – Zavael

ответ

3

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

Это нормально , хотя статический метод, подобный этому, должен быть потокобезопасным. – Groo

+0

да мужчина! его почти это ... но как я могу получить тип не из параметра, а из вызывающего класса, поэтому вместо Base.GetInstance () = Derived.GetInstance () я должен вызвать Base.GetInstance(), который возвращает Base и Derived.get .., который возвращает Derived – Zavael

+0

@Groo. Вы правы, но это может быть неприятно, если у вас есть критический код производительности (например, при обращении к методу много раз). Возможно, работа с двумя словарями (Swapping) улучшит производительность. –

3

Попробуйте шаблон абстрактного завода. Возможно, подходит и другое creational design patterns.

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

FooFactory.GetBarInstance().SomeDerivedMethod(); 
+0

завод не знает, какой экземпляр для создания производных классов ... – Zavael

+0

@ Zavael: вот почему он называется абстрактным. Если вам нужен Foo, вы используете FooFactory. Он может реализовывать общий интерфейс, но каждая фабрика создает свой собственный тип – Groo

0

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

public class Derived { 
    Derived instance; 

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

Да, это способ. Я хотел заставить любой производный класс реализовать одноэлементный метод GetInstance() через родительскую базу. – Zavael

+1

Вы не можете заставить реализацию статического метода в C# –

+0

да, я знаю, вот почему я попросил совета, если вообще можно добиться того, чего я хочу :) – Zavael

2

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

+1

+1 спасибо за lazysingleton1 double check :) лямбда-версия я не мог использовать, поскольку у меня нет одного экземпляра, но словарь синглетов – Zavael

Смежные вопросы