如何防止C#中的非法ICloneable <t>继承?

时间:2018-05-22 02:09:46

标签: c# oop generics inheritance inheritance-prevention

我有一个界面:

public interface ICloneable<out T>
    where T : ICloneable<T>
{
    T Clone();
}

应该接收实现此接口的类型(如下所示) 我可以创建一个实现它的类:

public class Class : ICloneable<Class>
{
    public Class Clone() { return (Class)MemberwiseClone(); }
}

太棒了!

但任何人都可以创建一个实现ICloneable&lt; T&gt;的类。 “错误的”。
是否存在阻止继承的方法,如下所示?(2个例子)

public class Other : ICloneable<Class>
{
    public Class Clone() { return new Class(); }
}

public class Other : Class, ICloneable<Class>
{
    public Class Clone() { return (Other)MemberwiseClone(); }
}

并允许继承如下所示? (任何来自2个例子)

public class Other : ICloneable<Other>
{
    public Other Clone() { return (Other)MemberwiseClone(); }
}

public class Other : Class, ICloneable<Other>
{
    public Other Clone() { return (Other)MemberwiseClone(); }
}

1 个答案:

答案 0 :(得分:3)

你不能重载一个类,所以:

public class Other : Class {}
public class Other : Class, IC<Other> {}

永远不会奏效。

现在,我要拉一个Jon Skeet,并展示你可能做到这一点,但后来不鼓励你去做。你可以这样做:

public class CloneableOther : Class, ICloneable<Other> {  }
public class Other : CloneableOther
{

}    

public class CloneableFoo : Class, ICloneable<Foo> { }
public class Foo : CloneableFoo
{

}

此代码正在做的是从继承中有效地删除泛型参数。除此之外,Foo仍然可以执行此操作:Foo : CloneableFoo, ICloneable<Other>,现在您必须为每个ICloneable实例创建两个类。

这就是为什么你首先需要这个?这是Foo : IInterface<Foo>的惯例,但是没有办法强制执行它。你最好的选择就是复制和粘贴,并确保课程匹配。

也许另一种方法是在Class的构造函数中检查ICloneable的类型是否是类的类型,并且如果它不是&#39;则抛出异常。如果它在运行时足够早地完成,那么这可能会感觉像编译时错误。