什么时候适合使用generics与inheritance?
使用generics而不是inheritance的情况及其相关的好处,反之亦然,它们应该如何最好地结合起来?
谢谢你的回答。
我将尽力说明这个问题的动机:我有一个如下所示的课程:
class InformationReturn where T : Info { InformationReturn(Employee employee, List) { ... } }
现在假设我有一个带有InformationReturn参数的存储库,它必须根据Info对象T的类型在数据库中编写不同的字段。 为T类型创建不同的存储库是否更好; 一个使用reflection来确定类型的存储库; 或者是否有更好的方法在generics上使用inheritancefunction?
注意 :其他客户端代码也必须根据T的类型进行不同的操作。
他们完全是不同的想法。 generics允许您以一般方式声明常见的“特定”function(冒着发出反应的风险)。 除了内部保存的数据类型之外, List
与List
作用不同。
虽然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允许您为操作提供默认实现,并允许子类覆盖它们。
参数化类型允许您更改类可以使用的类型。
但哪种方法最好取决于您的设计和实施限制
可重用面向对象软件的设计模式元素