2012-08-17 39 views
3

考慮以下幾點:繼承中的循環泛型 - 爲什麼它能夠工作?

public class EntityBase<TEntity> 
{ 
    public virtual void DoSomethingWhereINeedToKnowAboutTheEntityType() 
    { 
    } 
} 

public class PersonEntity : EntityBase<PersonEntity> 
{ 
    public override void DoSomethingWhereINeedToKnowAboutTheEntityType() 
    { 
    } 
} 

我加入到這個代碼並運行它和它的工作好,但我很驚訝,我可以繼承一個類誰的定義是基於繼承類。

當我嘗試它時,我期待它不要編譯,或者一旦實際調用失敗。

你可以做一個接口類似的東西:

public interface IEntityBase<TEntity> 
{} 

public class PersonEntity : IEntityBase<PersonEntity> 
{} 

其實我已經轉換我的代碼從以前的版本,使用的界面,但我仍然好奇,爲什麼這個工程。

+5

請注意,當您在對象上實現IComparable 和IEquatable 時,您一直都在執行此操作。 – 2012-08-17 12:19:27

+0

@FishBasketGordo。 TY編輯 - 混合我的VB和C#! – 2012-08-17 12:19:35

回答

3

我很驚訝,我可以繼承一個類誰的定義是基於繼承類。

小心 - 你所要繼承的一個類,其定義涉及任意Type,就是一切。所有這些都是合法的:

class O : EntityBase<object> 
class S : EntityBase<String> 
class Q : EntityBase<Q> 

所有你在EntityBase定義說是TEntity應該是一個型- 好,PersonEntity是一種類型,是不是?那麼,爲什麼它不能成爲TEntity?沒有理由不 - 因此它的工作原理。

你可能會擔心秩序的定義,但請記住,編譯的單元內,一切都被「馬上」定義 - 有沒有意義,其中PersonEntity需要「前」別的編譯(包括本身!)可以參考它。事實上,你甚至不允許

class A : EntityBase<B> 
class B : EntityBase<A> 

對於沒有想到的「編譯的秩序」可以工作,還需要如果這樣的事情。

+0

這是最適合我的答案。我一直都在使用泛型,是一個很棒的粉絲,但是讓我頭腦發呆。 (是星期五!) – 2012-08-17 12:42:22

4

它的工作原理是沒有理由不起作用。 EntityBase<PersonEntity>不從PersonEntity繼承,它只是引用類型。基類知道它自己的派生類沒有任何技術問題。這也適用(儘管這個具體的例子是一個壞主意):

public class A 
{ 
    public B AsB() 
    { 
     return this as B; 
    } 
} 


public class B : A 
{ 
} 
1

一個非常簡單的例子是通用接口IComparable<T>。通常情況下,要實現這樣的:

class MyClass : IComparable<MyClass> {/*...*/} 

通用模板的實現是隨便說MyClass對象可以比較其他MyClass對象。正如你所看到的,心智模式沒有問題。我可以很好地理解一個類的概念,它的對象可以在它們之間進行比較而無需瞭解類的任何其他信息。

這裏的要點是模板參數只是泛型類或接口使用,但它們不需要通過繼承關聯。 IComparable<MyClass>不會從MyClass繼承。所以沒有循環。