C# 实现泛型方法

C# 实现泛型方法,c#,.net,generics,c#-4.0,interface,C#,.net,Generics,C# 4.0,Interface,我用一种方法创建了一个接口,能够将一个对象的内容复制到同一类型的另一个对象中(实际功能与问题无关) 公共接口可理想化 { 无效克隆(T其他); } 我在正确的实现方面遇到了问题 我真正想要的是像这样实现它(这在ClassA中,它实现了IDeepClonable) public void DeepClone(A类其他) { 此.A=其他.A; } 但是,这不起作用,因为编译器不会将“other”对象识别为ClassA的实例(为什么?) 这也不起作用,因为它给出了一个“类型参数T的约束必须匹配(

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

公共接口可理想化
{
无效克隆(T其他);
}
我在正确的实现方面遇到了问题

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

public void DeepClone(A类其他)
{
此.A=其他.A;
}
但是,这不起作用,因为编译器不会将“other”对象识别为ClassA的实例(为什么?)

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

public void DeepClone<T>(T other) where T : ClassA
{
    this.A= other.A;
}
public void DeepClone(T other),其中T:ClassA
{
此.A=其他.A;
}
我可以通过将接口更改为接受对象而不是一般约束来解决所有问题,但我希望得到更优雅的解决方案

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

您正在尝试使用

你需要写作

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

public class ClassA : IDeepClonable<ClassA> {
    void DeepClone(ClassA other) { ... }
}
public interface IDeepClonable其中T:IDeepClonable
{
无效克隆(T其他);
}
公共类ClassA:理想可克隆{
void DeepClone(ClassA其他){…}
}
然而,这意味着任何使用
IDeepClonable
的代码本身都必须是泛型的,这最终会变得笨拙


CLR类型系统不够丰富,无法实现您真正想要的功能。

问题在于您在接口中声明了泛型方法,并且必须实现与派生类中完全相同的方法:

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

谢谢你的回复。不过我希望避免这种实现。顺便说一句,
DeepClone
是一个错误的名称;名为
DeepClone
的方法应该返回一个副本。您应该将其命名为
DeepCloneFrom
或类似的名称。我建议,如果您要进行大量深度克隆,最好使用方法
T AsImmutable()
IModifiableClone
使用方法
U AsNewMutable()
,来定义
iimmutableclone
,和
IFullClone
继承上述两项。不可变对象只需从其
AsImmutable()
实现返回自己
AsNewMutable()
将返回至少允许
U
契约所要求的任何突变方法的内容。在这里使用CRTP的一个问题是,一个人可能有一个基类,其中包括可克隆和不可克隆的派生,而不可克隆的派生可能有可克隆的子派生。将约束添加到
T
是否允许一个人做任何在没有约束的情况下不能做的事情?还有,有什么理由不把
T
设为协变(
out
)类型参数吗?@supercat:我没想到。这应该是逆变的(
in
),而不是协变的。
public interface IDeepClonable<out T> where T : IDeepClonable<T>
{
    void DeepClone(T other);
}

public class ClassA : IDeepClonable<ClassA> {
    void DeepClone(ClassA other) { ... }
}
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; 
         }
    } 
}