2012-08-17 46 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继承。所以没有循环。