C# 泛型:“X 其中 T: X”泛型类型约束的意义何在

本文关键字:约束 其中 泛型 泛型类型 | 更新日期: 2023-09-27 18:34:39

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

操作时间 – 创建基本实体

(...

  1. 将新类添加到项目的文件夹域,并将其称为实体。使类在 T 中抽象和泛型。您的代码应类似于以下代码片段:
 using System;
 namespace OrderingSystem.Domain
 {
     public abstract class Entity<T> where T : Entity<T>
     { }
 }

我的问题是:片段where T : Entity<T>的意义何在?

我知道 where 部分可以应用于在类型 T 上添加约束,但上面的代码看起来永远不可能实例化这样的类(如果它不是抽象的(。

C# 泛型:“X<T> 其中 T: X<T>”泛型类型约束的意义何在

这很可能是为了为返回(或接受(更多派生类型的实例的方法提供额外的类型安全性,使调用者不必将结果强制转换为派生更多的类型。

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();

编辑

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

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

附言只是为了说明如果你要去掉泛型约束,上面的示例会是什么样子:

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.