10

The following is contrived, but bear with me:

interface Clonable<TSubClass>
{
    TSubClass Clone();
}

How can I restrict TSubClass to be of the implementing type?

i.e only let the implementor do this:

class Dog : Clonable<Dog>
{
    Dog Clone() 
    {
        ....
    }
}

Not this:

class BadDog : Clonable<Rabbit>
{
    Rabbit Clone()
    {
        ....
    }
}
4

2 回答 2

8

不能强制执行,只能通过约定和文档......

我的惯例是使用类似TSelf.

interface ICloneable<TSelf> where TSelf : ICloneable<TSelf> { ... }

另请注意,任何实现或继承此接口的非具体构造都应通过...传递约束

[Serializable]
abstract class SerializableCloneable<TSelf> : ICloneable<TSelf> 
  where TSelf : SerializableCloneable<TSelf> { ... }

注意:我已经在NRoles中使用调用你的self-type parameterS的约定实现了这个检查。

于 2012-07-19T21:54:46.573 回答
3

您不能在编译时强制执行此操作,因为 .NET 泛型没有模板特化或鸭子类型。

但是,您可以包含一个静态构造函数(类型初始化程序),该构造函数使用反射在加载时断言关系。好的,C# 不允许您在接口上放置静态构造函数(即使 .NET 确实允许),因此您需要使用模块初始化程序或您自己调用的函数。此外,您还需要搜索实现接口的类型,包括尚未加载的类型(您可以订阅Assembly.Load事件,以便在将来加载类型时得到通知)。

于 2012-07-19T22:22:38.003 回答