2013-02-15 94 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