C#泛型:"X <T>哪里有T:X <T>"泛型约束是什么意思?

Paw*_*wan 19 c# generics

读一本书:NHibernate 3:初学者指南我发现了一个令我好奇的片段:

行动时间 - 创建基础实体

(......)

  1. 将新类添加到项目的文件夹域,并将其命名为Entity.在T中使类成为抽象和泛型.您的代码应类似于以下代码片段:
 using System;

 namespace OrderingSystem.Domain
 {
     public abstract class Entity<T> where T : Entity<T>
     { }
 }
Run Code Online (Sandbox Code Playgroud)

我的问题是:片段有where T : Entity<T>什么意义?

我理解该where部分可以应用于在类型上添加约束T,但上面的代码看起来似乎永远不可能实例化这样的类(如果它不是抽象的话).

Kir*_*kiy 30

这很可能意味着为返回(或接收)更多派生类型的实例的方法提供额外的类型安全性,从而使调用者不必将结果转换为更派生的类型.

abstract class Cloneable<T> where T : Cloneable<T>
{
    public abstract T Clone();
}

sealed class MyCloneable : Cloneable<MyCloneable>
{
    public override MyCloneable Clone()
    {
        return new MyCloneable();
    }
}

MyCloneable instance = new MyCloneable();
MyCloneable clone = instance.Clone();
Run Code Online (Sandbox Code Playgroud)

编辑

根据@ siride的评论,这被称为奇怪的重复模板模式.Eric Lippert撰写了一篇关于它在C#中的应用的精彩文章:

https://blogs.msdn.microsoft.com/ericlippert/2011/02/03/curiouser-and-curiouser/

PS并且只是为了说明如果你要删除泛型约束,上面的例子会是什么样子:

abstract class Cloneable
{
    public abstract Cloneable Clone();
}

sealed class MyCloneable : Cloneable
{
    public override Cloneable Clone()
    {
        return new MyCloneable();
    }
}

MyCloneable instance = new MyCloneable();
MyCloneable clone = (MyCloneable)instance.Clone(); // Note the cast.
Run Code Online (Sandbox Code Playgroud)

  • 它是这个的变种:https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern. (3认同)