2012-03-09 3 views
3

나는 GenericDao수퍼 클래스의 전달 하위 클래스는 <T>일까요?

internal class GenericDao<T> : IGenericDao<T> { 
} 

개체의 두 클래스라는 클래스가 있습니다

public class Empresa { 
} 

public class Assessoria : Empresa { 
} 

그리고 난이 일 EmpresaDao :

public class EmpresaDao { 

    private GenericDao<Empresa> parent { get; set; } 

    public EmpresaDao() { 
     this.parent = new GenericDao<Empresa>(); 
    } 
} 

어떻게 서브 클래스 Assessoria를 사용하여 GenericDao를 인스턴스화 ? 나는 이런 일을하지만 일하지 않는다 :

public class EmpresaDao { 

    private GenericDao<Empresa> parent { get; set; } 

    public EmpresaDao(Type type) { 
     if (type == typeof(Assessoria)) { 
      this.parent = new GenericDao<Assessoria>(); 
     } else { 
      this.parent = new GenericDao<Empresa>(); 
     } 
    } 
} 

답변

2

간단히 말해서, 정말로, 할 수 없다. 그러나 일반 인터페이스가 아닌 기본 인터페이스를 사용하거나 C# 4를 사용하고 일반 인터페이스 인터페이스를 사용하면 공변 또는 반 행위 (필요에 따라) 유형 매개 변수를 사용하면 약간의 속임수를 쓸 수 있습니다. 첫 번째 경우 :

interface IGenericDaoBase { 
} 

interface IGenericDao<T> : IGenericDaoBase { 
} 

public class EmpresaDao { 
    private IGenericDaoBase parent { get; set; } 
    public EmpresaDao(Type type) { 
     // same as before 
    } 
} 

틀림없이 디자인을 다시 생각해 보는 것이 좋습니다. 아마도 EmpresaDao은과 같이 사용되는 일반적인 매개 변수 자체를 수행 할 수 있습니다

public class EmpresaDao<T> where T : Empresa { 
    private GenericDao<T> parent { get; set; } 
    public EmpresaDao() { 
     this.parent = new GenericDao<T>(); 
    } 
} 

편집 : 사실, 더 나는 그것에 대해 생각, 더 나는 후자의 솔루션은 길을 가야하는 것입니다 생각합니다. 생성자의 type 매개 변수는 클래스 서명의 type 매개 변수와 동일한 역할을 수행합니다. 따라서 Type 객체 대신 generic 매개 변수를 전달하는 경우를 제외하면 호출 코드를 많이 변경하지 않아도됩니다.

1

시도해 보지 않는 것이 좋습니다. 버그가있는 경우 버그를 소개합니다.

변수가 a이고 b이고 모두 EmpresaDao 인 변수가 있다고 가정합니다. aEmpresa 부모로 초기화되고 bAssessoria 부모로 초기화됩니다. ab은 같은 유형이므로 모두 다른 하나 대신 사용할 수 있어야합니다. Assessoria이라고 가정하고 Empresa이 아닌 방법은 assess()입니다. 그러나 b.parentAssessoria이 될 것이므로 b.parent.assess()으로 전화를 걸지 만 a.parent.assess()으로 전화 할 수는 없습니다. 이는 ab이 처음에는 같은 유형이 아니어야 함을 의미합니다.

이 솔루션은 당신이 이제까지 .parent.assess()를 호출 여부에 따라 달라집니다 :

가) 당신은 항상 Empresa 될 부모의 시간 유형을 컴파일, EmpresaDao 클래스 내에서 .parent.assess()를 호출하지 할 수 결코됩니다.

public class EmpresaDao 
{ 
    private Empresa parent {get; set; } 
    public EmpresaDao(Func<Empresa> parentConstructor) 
    { 
     this.parent = parentConstructor();  
    } 
}  
static main() 
{ 
    var withEmpresaParent = new EmpresaDao(() => new Empresa()); 
    var withAssessoriaParent = new EmpresaDao(() => new Assessoria()); 
    .. 
} 

b) 귀하는 때때로 EmpresaDao 클래스 내에서 .parent.assess() 호출합니다 : 여기에 솔루션입니다. @siride 말했듯이 그럼 당신은 EmpresaDao 제네릭해야한다 :

public class EmpresaDao<T> where T : Empresa 
{ 
    private T parent {get; set;} 
} 

그러나, 당신이 뭔가 문제가 여전히 존재 의미합니다 .parent.assess()를 호출하기 전에 부모에 대한 런타임 검사를해야 할 것이다 경우 여전히 당신의 디자인. 그러나 무엇을 결정할 충분한 정보가 없습니다. 어쩌면 .assess() 메서드는 private이어야하며 외부에서 호출되지 않아야합니다.EmpresaEmpresa의 장식 자 여야합니다. "Empresa holding EmpresaDao"및 "Assessoria holding EmpresaDao"은 두 개의 다른 클래스 여야합니다. (아마 같은 인터페이스를 구현)

편집 : 이제는 제 솔루션에서 실수로 GenericDao 또는 GenericDao 대신 Empresa 또는 Assessoria 상위 유형을 만들었다는 것을 알았습니다. 내 메인 여전히 유효하지만 믿습니다.

관련 문제