2012-11-28 3 views
1

의 여러 버전을 대신 상속의 제네릭을 사용하는 방법, 다음과 같은 코드가 있다고 가정 해 고객의 전화는, 일부는기업에서 뭔가

질문은 ... 등 계정의 전화입니다 "이 가능하며 만약 그렇다면 그럼 어떻게?" Type을 플러그인 할 수있는 일반 Phone 클래스를 갖는 것이 가장 쉬울 것 같고 필요할 때 사용할 수있는 Type의 정보 (AccountID 또는 CustomerID) 만 사용하게됩니다. 또한이 DI없이 할 수 있는지 확인 해요 (생성자, 메서드 또는 속성을 통해 여부.) 나는 이런 식으로 뭔가 보일 것 내 머리에 무엇을 가지고

: 이것은 '아무튼

public interface IUsePhone 
{ 
    int GetOwnerID(); 
} 

public class Phone<T> where T : IUsePhone 
{ 
    //all of Phone's properties from above. 

    public int GetOwnerID() 
    { 
     //return T or item or something's GetOwnerID(); 
    } 
} 

public class Account : IUsePhone 
{ 
    private int _accountID; 

    //other Account members, including an AccountID property. 

    public int GetOwnerID() 
    { 
     return _accountID; 
    } 

    public Phone<Account> Phone { get; set; } 
} 

public class Customer : IUsePhone 
{ 
    private int _customerID; 

    //other Customer members, including an CustomerID property. 

    public int GetOwnerID() 
    { 
     return _customerID; 
    } 

    public Phone<Customer> Phone { get; set; } 
} 

을 t는 전화의 GetOwnerID() 현재 소유자의 GetOwnerID() 결과를 반환 할 수있는 방법이 없기 때문에 컴파일합니다. 나는이 같은 것을 볼 수 있었다 클라이언트 관점에서 최종 결과를 희망 :

Account myAccount = new Account(); 
myAccount.AccountID = 10; 

int ownerID = myAccount.Phone.GetOwnerID(); //this would return 10. 
+0

컴파일과 런타임이 혼란 스럽습니다. 무언가가 부족할 경우,'return default (T)'를 사용하여 컴파일 할 수있다. 'SetPhone (IUsePhone ..) '메소드가 있다면 고려해보십시오. 'Account/Customer'는'IUsePhone' 에서조차''전화 번호로 통일되지 않습니다. –

+0

이것은 어리석게 들릴지도 모릅니다. 실제로 내가 말하는 것을 할 방법이 없을 수도 있습니다. (SetPhone 메서드를 통해) 언급 한 것처럼 반사 또는 종속성 주입을 사용하지 않아도되기를 바랬습니다. 더 많이 생각할수록 두 옵션을 멀리 가져 가면 불가능 해 보이지만 실제로는 거기 사람들이 그래서 나는 그것이 가치가 있다고 생각했다. – IWriteApps

+1

팩토리 패턴 (http://www.dofactory.com/Patterns/PatternFactory.aspx) –

답변

4

나는 당신이하고 싶은 이유를 스스로에게 물어 필요가 있다고 생각합니다.

당신이 정말로 Phone 계약 이행이 모두 다른 종류의 무리를 원한다면, 당신은 인터페이스와 더 잘 플러스 아마도 추상 기본 구현은 다음과 같습니다

public interface IPhone 
{ 
    int PhoneID {get;set;} 
    string PhoneNumber {get;set;} 
} 

public abstract AbstractPhoneBase : IPhone 
{ 
    public int PhoneID {get;set;} 
    public string PhoneNumber {get;set;} 
} 

public CustomerPhone : AbstractPhoneBase 
{ 
    public int CustomerID {get;set;} 
} 
+0

@ f0x :)에 대한 작업처럼 보입니다. 좋은 생각입니다! :) –

+0

이것은 다소 우리가 우리 디자인에 지금 가지고있는 것입니다.내가 연구하고있는 것은 "CustomerPhone"과 "SomeOtherTypePhone"을 가지고 있어야하는 일에서 벗어날 수 있는지 알아 보는 것입니다. 그 이유는 모두 모두 소유자 ID의 NAME과 똑같기 때문입니다. CustomerPhone의 CustomerID 및 SomeOtherTypePhone의 SomeOtherTypeID. – IWriteApps

+0

이것이 사실이라면, 속성'string AdditionalIdDescripton'을 추가하고 일반 속성'string AdditionalId' 또는 상세한 사용 사례에 적용되는 것을 만드십시오. 이러한 값을 작은 닫힌 집합에 매핑해야하는 경우 문자열 대신에 "enum"을 사용할 수 있습니다. – SAJ14SAJ

0

나는 당신의 예라고 생각합니다 벌금 - 그냥 IUsePhone (계정, 고객, 등) 구현 소유자의 인스턴스에 걸리는 생성자가 누락되었습니다. 당신의 Phone<T> 클래스에이 추가

보십시오.

public IUsePhone Owner { get; private set; } 

    public Phone(T owner) 
    { 
     this.Owner = owner; 
    } 

    public int GetOwnerID() 
    { 
     return this.Owner.GetOwnerID(); 
    } 

참고 : 예에서, myAccount.Phone.GetOwnerID();를 호출 할 수 전에 전화 속성을 설정해야합니다 잊지 마세요.

것은 당신이 그것을 나는 추상 기본 클래스 경로 이미 제안을 내려 가서의 라인을 따라 기본 방법으로 전화를 설정합니다이 방법을 수행하는 경우 것이 :

public virtual void SetPhoneNumber<T>(string number) 
    { 
     this.Phone = new Phone<T>(this); 
     this.Phone.Number = number; 
    } 

그래서 당신의 useage이처럼 보이는 끝낼 것 이 :

Account myAccount = new Account(); 
    myAccount.AccountID = 10; 

    myAccount.SetPhoneNumber("123456"); 

    int ownerID = myAccount.Phone.GetOwnerID(); // this would return 10.