2012-01-23 3 views
2

나는 싱글 톤인 몇 가지 클래스를 가지고 있으므로 GetInstance (params) 메서드와 파생 클래스가있는 부모 BaseClass를 만들고이 메서드를 구현하고 theiselfs의 인스턴스를 반환해야합니다. 그들을 캐스팅하기 위해) ... 그들은 싱글 톤이므로 메서드는 정적이어야하지만 정적 메서드를 재정의 할 수는 없습니다. 코드를 작성하는 최선의 방법은 무엇입니까? 내가 원하는 것을 샘플 코드 : 내가자손의 싱글 톤 인스턴스를 반환합니다.

Derived.GetInstance().SomeDerivedMethod() 

을 호출 할이 외부 코드에서

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() as Derived).SomeDerivedMethod() and not 
new Derived().getInstance().SomeDerivedMethod() 

나는이 좋지 않아 알고, 내가 부족이 T 타입에 대한 경험도 있으므로 어떤 조언도 환영합니다. 감사

편집 :

또는 가능한 경우 든 파생 클래스를 ovwerride 필요하지 않도록, 자료의 getInstance() 메소드를 정의하지만,이 곳에서 클래스의 인스턴스를 반환합니다 그것은 ... Derived라고합니다 .GetInstance()는 Derived의 인스턴스를 반환합니다.

+1

이 클래스가 어떤 목적을해야합니까? IoC 컨테이너가 더 적합 할 수 있습니다. – Groo

+0

나는 더 많은 싱글 톤을 가질 것이므로, 부모로부터의 정적 상속 된 메소드가 항상 그것이 호출 된 곳의 타입의 인스턴스를 반환 할 수있는 방법으로 인스턴스를 생성하기위한 논리를 풀고 싶다. (자손 이어도) – Zavael

+0

여기있다. 비슷한 토론 http://www.codeguru.com/forum/showthread.php?t=376943 그리고 그것은 자손을 싱글 톤으로 강제 할 수있는 방법이없는 것처럼 보입니다. 나는 이상한 것을 원했던 것처럼 보입니다. :( – Zavael

답변

3

싱글 톤으로 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; 
     } 
    } 
} 
+0

괜찮습니다. , 이와 같은 정적 메서드는 스레드로부터 안전해야합니다. – Groo

+0

네! 그것의 거의 그것 ...하지만 어떻게 매개 변수가 아닌 호출 클래스에서 형식을 얻을 수 있습니다 Base.GetInstance 대신 () = Derived.GetInstance () 내가 Base.GetInstance()를 호출해야 Base 및 Derived – Zavael

+0

@Groo를 반환합니다. 성능에 중대한 코드가있는 경우 (예 : 메서드에 여러 번 액세스 할 때) 좋지는 않을 수 있습니다. 어쩌면 2 개의 사전 (스와핑)으로 작업하면 성능이 향상 될 것입니다. –

3

추상 팩토리 디자인 패턴을 사용해보십시오. 다른 creational design patterns도 적합 할 수 있습니다.

당신은 공장 수준에서 "싱글 - 다움"을 시행해야하고, 같은 다음 호출은 보일 수 있습니다 :

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

the factory 모르겠다, 파생 된 클래스를 생성하는 인스턴스 ... – 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

lazysingleton1 +1 감사합니다 :) 람다 버전은 싱글 인스턴스가 아니지만 사용할 수 없습니다. 단 하나의 사전 – Zavael