什么时候适合使用generics与inheritance?

使用generics而不是inheritance的情况及其相关的好处,反之亦然,它们应该如何最好地结合起来?

谢谢你的回答。

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

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

现在假设我有一个带有InformationReturn参数的存储库,它必须根据Info对象T的类型在数据库中编写不同的字段。 为T类型创建不同的存储库是否更好; 一个使用reflection来确定类型的存储库; 或者是否有更好的方法在generics上使用inheritancefunction?

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

他们完全是不同的想法。 generics允许您以一般方式声明常见的“特定”function(冒着发出反应的风险)。 除了内部保存的数据类型之外, ListList作用不同。

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

编辑

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

generics和inheritance是两个不同的东西。 inheritance是一种OOP概念,generics是一种CLRfunction,允许您在编译时为公开它们的类型指定类型参数。

inheritance和generics实际上可以很好地协同工作。

遗产:

inheritance允许我创建一个类型:

 class Pen { } 

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

 class FountainPen : Pen { } 

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

generics:

generics是一个CLRfunction,让我创建这样的类型:

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

现在,当我使用Foo我可以通过提供generics类型参数来指定T类型:

 Foo foo = new Foo(); 

现在,因为我已经指定T应该是我刚刚创建的对象的int ,所以Foo.Bar的类型也将是int因为它被声明为T类型。

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

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

(等) – 这里T是类型参数。 通用方法类似:

 public void Foo(T item) 

调用代码指定它想要使用的类型参数 ,例如

 List list = new List(); list.Add("hi"); 

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

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

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

如果要创建可应用于许多未知类样式的“模板”,请使用generics。 例如。 藏品??? 非常适合仿制药。 inheritance是指当你有一个基本视锥,孩子“是”这个概念的扩展。

我的一般规则

  • 如果你开始在你的代码中定义属性作为对象并输入很多类型,那么它可能是generics的时间。
  • 如果你想针对“更高概念”以及派生类进行编程,那么它的inheritance。
  • 如果你的课程要包括或在一个音乐会课程上工作,那么它的generics。
  • 如果你依赖于一个未知的“未定义”类的细节,那么你可能更好地使用generics。
  • 如果派生类是“是一个”那么它通常是inheritance
  • 如果你的超类“使用了一些x”那么它的generics。

inheritance更多地是关于“is-a”(青蛙是动物),其中generics是关于创建作用于类型数据的容器(T的列表,T的处理器等)。 它们不是相互排斥的

如果你愿意,你可以拥有:

 public class Base { } public class Derived : Base { } 

inheritance和参数化类型都不能在运行时更改

inheritance允许您为操作提供默认实现,并允许子类覆盖它们。

参数化类型允许您更改类可以使用的类型。

但哪种方法最好取决于您的设计和实施限制

可重用面向对象软件的设计模式元素