将接口上的泛型参数限制为子类

she*_*mus 10 c# generics parameters restrictions

以下是人为的,但请耐心等待:

interface Clonable<TSubClass>
{
    TSubClass Clone();
}
Run Code Online (Sandbox Code Playgroud)

如何将TSubClass限制为实现类型?

即只让实现者这样做:

class Dog : Clonable<Dog>
{
    Dog Clone() 
    {
        ....
    }
}
Run Code Online (Sandbox Code Playgroud)

不是这个:

class BadDog : Clonable<Rabbit>
{
    Rabbit Clone()
    {
        ....
    }
}
Run Code Online (Sandbox Code Playgroud)

Jor*_*dão 8

不能只通过惯例和文件强制执行....

我的惯例是使用类似的东西TSelf.

interface ICloneable<TSelf> where TSelf : ICloneable<TSelf> { ... }
Run Code Online (Sandbox Code Playgroud)

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

[Serializable]
abstract class SerializableCloneable<TSelf> : ICloneable<TSelf> 
  where TSelf : SerializableCloneable<TSelf> { ... }
Run Code Online (Sandbox Code Playgroud)

注意:我已经使用调用自我类型参数的约定在NRoles中实现了此检查.S


Ben*_*igt 3

您无法在编译时强制执行这一点,因为 .NET 泛型没有模板专门化或鸭子类型。

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