4

我用一种方法创建了一个接口,能够将一个对象的内容复制到另一个相同类型的对象中(实际功能与问题无关)。

public interface IDeepClonable
{
    void DeepClone<T>(T other);
}

我在正确实施时遇到了麻烦。

我真正想要的是像这样实现它(这是在 ClassA 内部,它实现了 IDeepClonable)

public void DeepClone<ClassA>(ClassA other)
{
    this.A = other.A;
}

但是这不起作用,因为编译器不将“其他”对象识别为 ClassA 的实例(为什么?)

这也不起作用,因为它给出了“类型参数 T 的约束必须匹配 (...) 接口方法。

public void DeepClone<T>(T other) where T : ClassA
{
    this.A= other.A;
}

我可以通过更改接口以接受对象而不是通用约束来解决所有问题,但我希望有一个更优雅的解决方案。

我也可以通过将接口转换为通用接口来解决这个问题,但这会迫使我强制转换为该通用接口。

4

2 回答 2

5

您正在尝试使用CRTP

你需要写

public interface IDeepClonable<out T> where T : IDeepClonable<T>
{
    void DeepClone(T other);
}

public class ClassA : IDeepClonable<ClassA> {
    void DeepClone(ClassA other) { ... }
}

然而,这意味着任何使用的代码IDeepClonable本身都必须是通用的,这最终会变得笨拙。

CLR 类型系统不够丰富,无法满足您的需求。

于 2012-05-07T15:55:09.447 回答
0

问题是你在接口中声明了一个泛型方法,你必须在派生类中实现完全一样的方法:

public class ClassA : IDeepClonable 
{ 
    void DeepClone<T>(T other) { /* some implementation here */ } 
} 

与此不同的东西是行不通的。

就是说,为什么需要这种复杂性,这里不需要泛型,只需实现为:

public interface IDeepClonable 
{ 
    void DeepClone(IDeepClonable other); 
} 

public class ClassA : IDeepClonable 
{ 
    void DeepClone(IDeepClonable other)
    {
         // just to be sure ....
         if (other is ClassA) 
         {
             var o = (ClassA)other;
             this.A = o.A; 
         }
    } 
} 
于 2012-05-07T16:04:37.463 回答