2013-06-13 2 views
1

나는이 간단한 복제 인터페이스를 사용하고 싶습니다. 컴파일해야하는 것처럼 보이지만 그렇지 않습니다. 내 BObject 클래스에 DeepClone()이 구현되어 있지 않다는 메시지가 나타납니다. 나는 DeepClone() 방법을 가지고 있고 BObject 클래스 IObject을 구현하고 있기 때문에 이것을 이해할 수 없습니다.왜 내 복제 코드가 컴파일되지 않습니까?

interface IDeepCloneable<T> 
{ 
    T DeepClone(); 
} 

interface IObject : IDeepCloneable<IObject> 
{ 
    string Name { get; } 
    double Sales { get; } 
} 

//'BObject' does not implement interface member 
// 'IDeepCloneable<IObject>.DeepClone()' 
class BObject : IObject 
{ 
    public string Name { get; set; } 
    public double Sales { get; set; } 

    public BObject DeepClone() 
    { 
     return new BObject() { Name = this.Name, Sales = this.Sales }; 
    } 
} 

내 인터페이스가 잘못되었다고 선언하고 있습니까?


또는 어쩌면 DeepClone 구현? 이 코드를 사용할 수 있습니다

public IObject DeepClone() //returns an IObject instead of a BObject 
{ 
    return new BObject() { Name = this.Name, Sales = this.Sales }; 
} 

내가 가진 문제는 BObject.DeepClone() 방법은 결과로 BObject을 반환한다는 체크가 없습니다 것입니다. 나는이처럼 보이는 클래스 수 :이 클래스를 사용

class BObjectImposter : IObject 
{ 
    public string Name { get; set; } 
    public double Sales { get; set; } 

    public IObject DeepClone() 
    { 
     //returns a BObject instead of a BObjectImposter 
     return new BObject() { Name = this.Name, Sales = this.Sales }; 
    } 
} 

을,이를 작성할 수

BObjectImposter objImp = new BObjectImposter(); 
IObject copy = objImp.DeepClone(); 

내가 copyBObjectImposter의 구현임을 예상 할 수 있지만, 실제로 구현입니다 관련이없는 클래스 BObjectIObject을 구현합니다. 나는 인터페이스의 요점은 내가 어떤 구현을 사용 하느냐가 중요하지 않다는 것을 이해하지만 이것은 나에게 좋은 코드처럼 보이지 않는다. 어쩌면 내 BObjectImposter 구현 어딘가에 DeepClone()BObjectImposter 객체를 반환 할 것으로 예상됩니다. 또한 IObject의 한 구현은 IObject의 다른 구현에 의존하지 않아야합니다.


어쩌면 내가 IObject 추상 클래스를 만들 수 거기 DeepClone()을 선언합니다. 이것은 하나의 구현 (ObjectA 호출) 내 구현을 가지고있는 것 같아요 어디 Name 설정하기 전에 생성자에서 Sales을 설정하고 다른 구현 (ObjectB)을 호출해야 할 때 을 설정하기 전에 Name을 설정해야합니다. 건설자. 그 DeepClone() 방법은 IObject을 반환해야합니다, 그래서 당신은 당신의 질문에 암시했듯이

답변

5

, IObject는 IDeepClonable < IObject>를 구현합니다.

당신은 CRTP 모든 방법을 사용할 필요가 :

interface IObject<T> : IDeepCloneable<T> where T : IObject<T> 
class BObject : IObject<BObject> 

IObject는 IDeepCloneable<IObject> 그래서 DeepCloneIObject을 반환 상속되기 때문에

+0

코드를 사용하면 인터페이스를 어떻게 사용합니까? 예를 들어,이 줄은'IObject a = new BObject(); '라는 에러를 발생시킵니다. – user2023861

+0

@ user2023861 : 'IObject '를 사용하는 모든 메소드는 차례로 일반화되어야합니다.C#이 상위 유형의 유형을 지원하지 않기 때문에이 매우 귀찮은 제한이 있습니다. 'IObject'를'T'에서 공변 (covariant) 시켜서 항상'IObject '를 사용할 수 있습니다. – SLaks

1

그것을 (당신은 또한 IDeepCloneablewhere T : IDeepCloneable<T>을 추가한다고). 다음은 작동해야합니다 :

interface IDeepCloneable<T> 
{ 
    T DeepClone(); 
} 

interface IObject<T> : IDeepCloneable<T> 
{ 
    string Name { get; } 
    double Sales { get; } 
} 

//'BObject' does not implement interface member 
// 'IDeepCloneable<IObject>.DeepClone()' 
class BObject : IObject<BObject> 
{ 
    public string Name { get; set; } 
    public double Sales { get; set; } 

    public BObject DeepClone() 
    { 
     return new BObject() { Name = this.Name, Sales = this.Sales }; 
    } 
} 
+0

이 인터페이스는 어떻게 사용합니까? 이 코드'IObject a = new BObject();'는'IObject는 1 개의 타입 인자를 필요로합니다. '라는 에러를 내게합니다. 나는'IObject = new BObject(); '를 사용할 수는 있지만 인터페이스 사용에 대한 생각을 깨뜨리는 것처럼 보입니다. – user2023861

+1

그런 정적 타이핑 문제는 두려웠습니다. 호출 클래스/메소드에 return Type 인수를 전달해야합니다. 그 이유는 Microsoft가 ICloneable을 제네릭으로 업데이트하지 않았기 때문입니다. – pingoo

관련 문제