什么时候适合使用泛型与继承?

Laz*_*Laz 8 .net c# vb.net generics inheritance

使用泛型而不是继承有什么情况及其相关的好处,反之亦然,它们应该如何最好地结合起来?

谢谢你的回答.

我将尽力说明这个问题的动机:我有一个如下所示的课程:

class InformationReturn<T> where T : Info
{
    InformationReturn(Employee employee, List<T>) { ... }
}
Run Code Online (Sandbox Code Playgroud)

现在假设我有一个采用InformationReturn参数的存储库,它必须根据Info对象T的类型在数据库中编写不同的字段.为T类型创建不同的存储库是否更好; 一个使用反射来确定类型的存储库; 或者是否有更好的方法使用继承功能/使用泛型?

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

And*_*are 12

泛型和继承是两个不同的东西.继承是一种OOP概念,泛型是一种CLR功能,允许您在编译时为公开它们的类型指定类型参数.

继承和泛型实际上可以很好地协同工作.

遗产:

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

class Pen { }
Run Code Online (Sandbox Code Playgroud)

然后创建另一个扩展的类型Pen:

class FountainPen : Pen { }
Run Code Online (Sandbox Code Playgroud)

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

泛型:

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

class Foo<T> 
{
    public T Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

Foo<int> foo = new Foo<int>();
Run Code Online (Sandbox Code Playgroud)

现在,既然我已经指定Tint对于我刚刚创建的对象,那么它的类型Foo.Bar也将int被声明为类型T.

  • 但什么时候应该使用每个? (4认同)

C. *_*oss 10

我认为当你只想要应用于各种类型(Add,Remove,Count)的相同功能时,你应该使用泛型,它将以相同的方式实现.继承是指您需要相同的功能(GetResponse)但希望以不同的方式实现它.

  • IMO,这实际上是这个问题的最佳答案!搜索SE约20分钟后.. (3认同)

Jon*_*eet 10

使用泛型来指定算法或类型的行为,该行为可以用某种"未知类型"表示,同时保持根据该未知类型强类型化的API.未知类型称为类型参数,并在代码中表示如下:

public class List<T>
{
    public void Add(T item)
}
Run Code Online (Sandbox Code Playgroud)

(等) - 这T是类型参数.通用方法类似:

public void Foo<T>(T item)
Run Code Online (Sandbox Code Playgroud)

调用代码指定的类型参数,它希望有,例如工作

List<string> list = new List<string>();
list.Add("hi");
Run Code Online (Sandbox Code Playgroud)

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

我真的不能想到很多地方他们是彼此的替代品......

  • 虽然我没有向你投票,但你的答案却毫无用处.OP显然是.NET的新手,你的极短而简洁的字典定义可能很难解决他/她的任何困惑. (3认同)

Ada*_*son 6

他们完全是不同的想法.泛型允许您以一般方式声明常见的"特定"功能(冒着发出反应的风险).除了内部保存的数据类型之外,A List<int>与a的功能不同List<string>.

虽然继承可以用来做同样的事情,但我可以创建一个List类,然后是IntList一个StringList继承它的类和一个类.我可以很容易地使这两个类的功能完全不同,或者在另一个类中提供一个不可用的功能.

编辑

在查看问题的编辑后,答案排序是"它取决于".您可以为双方制作参数 - 事实上,LINQ to SQL和实体框架都是使用泛型的反射检查和强类型实体类以及其他存储库类的组合.你当然可以采用你所看到的方法,只要知道,一般来说,一个可以通过反射或其他东西解决的问题,当被"别的东西"解决时,它会变得更快.它取决于您在性能,可维护性,可读性和可靠性方面需要多少权衡.

  • 这个答案帮助我指出,当行为和继承没有区别时,我应该使用泛型,否则,谢谢。我已经修改了这个问题,以便更清楚地说明我的动机。 (2认同)

Rob*_*sey 5

当您要创建可应用于多种样式的未知类的“模板”时,请使用泛型。例如。收藏藏品??? 是仿制药的良好候选者。当您有一个基本概念认为子代“是”该概念的扩展时,即表示继承。

我的一般规则

  • 如果您开始在代码中将属性定义为Object并进行大量类型转换,则可能是泛型的时间。
  • 如果要针对“更高概念”以及派生类进行编程,则可以继承它。
  • 如果您的班级要包装或在协奏班上工作,则使用其泛型。
  • 如果您依赖于未知的“尚待定义”类的细节,那么使用泛型可能会更好。
  • 如果派生类是“是”,则通常继承
  • 如果您的超类“使用一些x”,则其泛型。