2009-08-07 2 views
0

는 기본적으로 내 설정은 이것이다 :기본 클래스의 유형을 조정하는 반환 유형의 기본 클래스를 가질 수 있습니까?

public abstract class BaseObject{ 
    public abstract BaseObject Clone(); 
} 

public class DerivedObject : BaseObject{ 
    public DerivedObject Clone() 
    { 
     //Clone logic 
    } 
} 

이 방법을 재정의 할 때 반환 형식을 변경할 수 없기 때문에 위의 코드는 컴파일되지 않습니다.

모든 파생 된 형식의 Clone 메서드가 자신의 형식 (아마도 제네릭을 통해)의 인수를 반환 할 수 있습니까? 당신이 발견 한 것처럼

답변

3

음, C#을 공변 반환 형식을 허용하지 않습니다 ...하지만 당신 사용 제네릭 :

public abstract class BaseObject<T> where T : BaseObject<T> 
{ 
    public abstract T Clone(); 
} 

public class DerivedObject : BaseObject<DerivedObject> 
{ 
    public override DerivedObject Clone() 
    { 
     // ... 
    } 
} 

이 솔루션은 다양한 방법으로 통증이있을 수 있습니다 - 아니 적어도 때문에 이해하기 어렵지만 많은 상황에서 합리적으로 잘 작동 할 수 있습니다.

편집 : T에 대한 제약 조건을 포함시킨 이유는 T 인 경우에 인스턴스에서 "자체"메서드를 호출 할 수 있기 때문입니다. 일반적으로 매우 편리합니다. 그래도 필요하지 않으면 제약 조건을 잃을 수 있습니다.

+0

이 솔루션이 어려울 수있는 다양한 방법을 설명해 주시겠습니까? 나는 Clone 메서드를 사용할 때마다 매번 타입 변환하지 않아도 안되는 고통 때문에이 고통을 감수 할 가치가 있는지 알아 내려고합니다. – chrischu

+0

@Mehrdad : 고마워. @crischu : 음, 다른 클래스가'BaseObject '에서 파생 될 수 없다는 것은 말할 것도 없습니다. 그래서 절대 안전한 것은 아닙니다. IMessage 여기서 TMessage : IMessage TBuilder : IBuilder 여기서, 다른 타입과 상호 작용할 필요가 있다면, 예를 들어. 추잡한. 그것은 대부분 괜찮아요,하지만 당신은 멋진 머리를 유지해야합니다. –

0

다음과 같이 할 수 있습니다. 기본 (T)를 반환하는 대신 복제 논리에 따라 무언가를 반환하십시오. 그런데

public class MyBase<T> 
{ 
    public T Clone() 
    { 
     return default(T); 
    } 
} 

public class MyDerived : MyBase<MyDerived> 
{ 
} 

, 나는 이진 serializer를 사용하여 메모리에 현재의 객체를 직렬화 같은 개체 복제를 위해, 새로운 인스턴스로 다시 그 메모리를 역 직렬화.

관련 문제