2009-04-28 108 views
7

使用泛型超越继承的情况及其相关好处,反之亦然,它们应该如何最好地组合?什么时候适合使用泛型与继承?

谢谢你的答案。

我要去尝试陈述的动机这个问题,尽我所能: 我有一个类,如下图所示:

class InformationReturn<T> where T : Info 
{ 
    InformationReturn(Employee employee, List<T>) { ... } 
} 

现在假设我有一个资料库,它接受一个I​​nformationReturn说法,必须根据Info对象T的类型在DB中划分不同的字段。为T类型创建不同的存储库会更好吗?一个使用反射来确定类型的存储库;或者有更好的方法使用泛型的继承功能?

注意:其他客户端代码也必须根据T的类型进行不同的操作。

回答

4

他们完全是真正不同的想法。泛型允许您以一般方式声明通用的“特定”功能(冒着听起来很矛盾的风险)。 A List<int>的功能与List<string>的功能不同,除了里面的数据类型。尽管可以使用继承来做同样的事情,但我可以创建一个List类,然后创建一个类IntList和一个StringList类,该类继承自其中。我可以很容易地使这两个类的功能完全不同,或者使另一个功能不可用。

编辑

审查编辑的问题后,得到的答复是sortof“看情况”。你可以为双方进行争论 - 实际上,LINQ to SQL和实体框架都是使用泛型进行反射检查和强类型实体类以及其他存储库类的组合。你当然可以采取你所看到的方法,只要知道,一般来说,一个可以通过反射或其他方式解决的问题在被“其他方法”解决时可能会更快。这取决于您在性能,可维护性,可读性和可靠性方面需要多少折衷。

+0

这个答案帮助我指出我应该使用泛型时没有行为上的差异并继承,否则,谢谢。 我已经修改了这个问题,以便更清楚我的动机。 – Laz 2009-04-28 21:02:35

10

泛型和继承是两个独立的东西。继承是一种OOP概念,泛型是一种CLR特性,它允许您在编译时为暴露它们的类型指定类型参数。

继承和泛型实际上在一起很好地工作。

继承:

继承允许我创建一个类型:

class Pen { } 

再后来创建一个扩展其他类型Pen

class FountainPen : Pen { } 

这是有用的,因为我可以重用基类的所有状态和行为,并公开中的任何新行为或状态。继承允许我快速创建现有类型的更具体的版本。

泛型:

泛型是一个CLR功能,可以让我创建一个类型是这样的:

class Foo<T> 
{ 
    public T Bar { get; set; } 
} 

现在,当我使用Foo<T>我可以指定T类型将通过提供什么泛型类型参数:

Foo<int> foo = new Foo<int>(); 

现在,由于我已经指定了T应为我刚刚创建的对象的intFoo.Bar的类型也将是int,因为它被声明为T

+3

但是什么时候应该使用每个? – 2009-04-28 19:00:12

+1

pedantry的挑剔:你提供了泛型类型*参数*,即T是类型参数,int是类型参数。我会让你决定是否值得编辑:) – 2009-04-28 19:14:35

+0

修正!感谢您指出这一点,pedantry永远不会不受欢迎 - 善良知道我自己发出大量:) – 2009-04-28 19:17:20

3

继承关于“is-a”(青蛙是动物)的地方更多,泛型是关于创建容器的类型化数据(T的列表,T的处理器等)。他们是不互相排斥

,如果你愿意,你可以有这样的:

public class Base<T> 
{ 

} 

public class Derived : Base<Foo> 
{ 

} 
+0

而事实上,你可以有通用的接口:public interface IBase - > public abstract Base :IBase - > public class Derived:Base 2009-04-28 19:00:58

4

我想你应该使用泛型当你只需要将相同的功能应用于各种类型(添加,删除,计数),它将以相同的方式实现。继承是当你需要相同的功能(GetResponse),但希望以不同的方式实现它。

7

使用泛型来指定一个算法或类型的行为,它可以用一些“未知类型”来表示,同时保留一个强类型的未知类型的API。未知类型被称为一个类型参数并在代码中表达这样的:

public class List<T> 
{ 
    public void Add(T item) 
} 

(等) - 这里T是类型参数。泛型方法是相似的:

public void Foo<T>(T item) 

调用代码指定类型参数它想用,例如工作

List<string> list = new List<string>(); 
list.Add("hi"); 

使用继承来专门化类型的行为。

我真的不能相信许多地方,他们相互替代的......

4

使用泛型当你想创建一个“模板”,可以适用于多种风格的类别未知。例如。收藏品?是仿制药的良好候选者。继承是指当你有一个基础锥体时,孩子们“是”这个概念的延伸。

我的一般规则

    如果你开始定义代码中的性质在作为对象和类型转换了很多,那么它可能是时间泛型
  • 如果您想针对“更高的概念”以及派生类,然后继承它进行编程。
  • 如果你的班级要包装或工作在音乐会类,那么它的泛型。
  • 如果你依赖于一个未知的“尚未定义”类的细节,那么你可能更好地使用泛型。
  • 如果派生类是“是”,那么它的通常继承
  • 如果你的超类“使用一些x”,那么它的泛型。