如何防止 C# 中的非法 ICloneable<T> 继承?
How to prevent illegal ICloneable<T> inheritance in C#?
我有一个接口:
public interface ICloneable<out T>
where T : ICloneable<T>
{
T Clone();
}
应该接收实现此接口的类型(如下所示)。
我可以创建一个 class 来实现它:
public class Class : ICloneable<Class>
{
public Class Clone() { return (Class)MemberwiseClone(); }
}
太棒了!
但是任何人都可以创建一个 class 实现 ICloneable "wrong"。
是否存在如下所示的防止继承的方法?(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(); }
}
您不能重载 class,因此:
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
实例创建两个 classes。
这就是 为什么 你首先需要这个? Foo : IInterface<Foo>
是一种惯例,但没有办法强制执行。最好的办法是只进行复制和粘贴,并确保 class 匹配。
也许另一种方法是在 Class
的构造函数中检查 ICloneable
的类型是否是 class 的类型,然后抛出异常如果不是,那感觉就像是编译时错误,如果它在运行时足够早地完成的话。
我有一个接口:
public interface ICloneable<out T>
where T : ICloneable<T>
{
T Clone();
}
应该接收实现此接口的类型(如下所示)。
我可以创建一个 class 来实现它:
public class Class : ICloneable<Class>
{
public Class Clone() { return (Class)MemberwiseClone(); }
}
太棒了!
但是任何人都可以创建一个 class 实现 ICloneable
是否存在如下所示的防止继承的方法?(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(); }
}
您不能重载 class,因此:
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
实例创建两个 classes。
这就是 为什么 你首先需要这个? Foo : IInterface<Foo>
是一种惯例,但没有办法强制执行。最好的办法是只进行复制和粘贴,并确保 class 匹配。
也许另一种方法是在 Class
的构造函数中检查 ICloneable
的类型是否是 class 的类型,然后抛出异常如果不是,那感觉就像是编译时错误,如果它在运行时足够早地完成的话。