2013-02-15 114 views
0

背景实例化一个类型受限泛型类没有子它

阅读,当我遇到这个通用类,定义跌跌撞撞[如果你不感兴趣的背景跳到问题]一天,这难倒我了一段时间:

public abstract class Entity<T> where T : Entity<T> 

我困惑的是如何TEntity<T>本身可以是Entity<T>。这似乎是某种奇怪的递归约束。

我才明白,这个约束可以通过子类(这是当然的,什么abstract要求很高之类的)来满足:

public class Deriver : Entity<Deriver> 

这里,类型T的保证下,为类型Entity<T>因为Deriver派生自Entity<Deriver>

问题

总之,它使我怀疑,如果类是不是抽象的,我们可以直接instantitate呢?

因此,考虑

class Entity<T> where T : Entity<T> 

我们可以直接instantitate Entity<T>

显然,我们不能说:

Entity<SomeClass> e = new Entity<SomeClass>(); 

因为SomeClass不满足约束where T : Entity<T>

忽略显而易见的“你为什么想这么做?”这基本上是一种确保在不使用abstract关键字之前就可以使用它的方法吗?

+0

我把它叫做“型系统地狱” :) – Ankur 2013-02-15 10:57:56

+2

埃里克利珀的经典博客文章的主题:http://blogs.msdn.com/b/ericlippert/archive/2011/ 02/03 /奇怪之和 - curiouser.aspx。 TL; DR:不,它不是用来派生的(“抽象”已经做得很好)。它被用作在涉及类层次结构的某些情况下提供类型安全性的尝试。 – Jon 2013-02-15 11:07:51

回答

2

该假设不正确。下面将编译:

var e = new Entity<Deriver>(); 
+0

你确定?我刚刚尝试过,并报告错误:'类型'Deriver'不能用作泛型类型或方法'实体'中的类型参数'T'。没有从Deriver到Entity 的隐式引用转换 – 2013-02-15 11:00:29

+1

@JamesWiseman:对于上面给出的Deriver的定义,它会进行编译。对于某些随机的SomeClass而言,它不会。 – Jon 2013-02-15 11:02:55

+0

对,这很有道理。谢谢。 – 2013-02-15 11:09:19