2012-05-08 3 views
3

기본 클래스의 생성자를 재정의하는 데 어려움을 겪고있는 준 복합 상속 구조가 있습니다. 다음 코드는 오류를 표시 할 수 있습니다.상속 된 클래스에 문제가 발생했습니다. generics가있는 생성자

public abstract class MyBaseObject 
{ 
    public MyBaseObject(MyBaseCollection<MyBaseObject> parent) 
    { 
     this.Parent = parent; 
    } 

    public MyBaseCollection<MyBaseObject> Parent { get; set; } 
} 

public abstract class MyBaseCollection<T> 
    where T : MyBaseObject 
{ } 

public class MyRealObject : MyBaseObject 
{ 
    public MyRealObject(MyRealCollection parent) 
     : base(parent) 
    { } 

    public new MyRealCollection Parent { get { return (MyRealCollection)base.Parent; } } 
} 

public class MyRealCollection : MyBaseCollection<MyRealObject> 
{ } 

따라서 MyBaseObject 클래스의 생성자를 재정의 할 수 없습니다. MyBaseCollection 대신 MyRealCollection을 전달하려는 것은 허용되지 않습니다. 제네릭 인수를 제거하면 작동합니다. MyRealCollection은 MyBaseCollection 대신 허용됩니다. 하지만 제 컬렉션 클래스가 필요한 방식으로 작동하도록하려면 제네릭 인수가 필요합니다.

+0

C# 4를 사용하는 경우이 질문과 대답을보고 싶을 수 있습니다. 문제에 대한 직접적인 대답이 아닐 수도 있지만 코드를 약간 리팩터링하려는 경우 도움이 될 수 있습니다. http://stackoverflow.com/q/9203352/250725 – psubsee2003

답변

3

의 인스턴스에 통과했다하지 않을 경우

는하지만, MyBaseObject의 관점에서 완벽하게 합법적 것
public MyBaseObject(MyBaseCollection<MyBaseObject> parent) 
{ 
    this.Parent = parent; 
    parent.Add(new SomeOtherRealObject()); 
} 

내가 제안 : MyBaseObject의 생성자이 그랬다면 왜의 아이디어를 들어, 상상 당신은 공분산과 공분산을 들여다 봅니다. 여기에 좋은 시작이 될 수도 있습니다 http://msdn.microsoft.com/en-us/library/dd799517.aspx

요약하면 CLR은 유료 등급보다 높은 이유로 잘 정의 된 이유로 인해 유형 상속에 대해 가정 할 수 없습니다.

그러나 유형 계층 구조를 조금만 사용하면 이와 같은 작업을 수행 할 수 있습니다. 내가 도움이 IEnumerable 사용됩니다.

public abstract class MyBaseObject 
{ 
    public MyBaseObject(IEnumerable<MyBaseObject> parent) 
    { 
     this.Parent = parent; 
    } 

    public IEnumerable<MyBaseObject> Parent { get; set; } 
} 

public class MyRealObject : MyBaseObject 
{ 
    public MyRealObject(MyRealCollection parent) 
     : base(parent) 
    { } 

    public new MyRealCollection Parent { get { return (MyRealCollection)base.Parent; } } 
} 

public class MyRealCollection : IEnumerable<MyRealObject> 
{ } 
+2

+1. T가 out 형 매개 변수로 정의 되었기 때문에 특히 IEnumerable 으로 이것을 할 수 있습니다. 이것은 인터페이스상에서 연산의 출력으로 만 사용되기 때문에 외부의 힘에 의해 간섭 될 수 없습니다. 내 대답의 예를 들어) –

+0

@ 크리스 +1, 설명 주셔서 감사합니다. – Squirrelsama

+1

이 열쇠는 인터페이스를 사용하는 것이 었습니다. (실제 프로젝트에서 사용하고 있습니다.이 예제에서는 단순화했습니다.) 콜렉션에서 T generics를 밖으로 선언하십시오. – Random

3

MyBaseCollection은가 아니라 MyRealObject의 모음이기 때문에 MyRealCollection 대신 사용할 수 있습니다. 당신이 MyRealCollection