为什么不继承列表<T>?
在规划我的程序时,我通常会从这样的一连串想法开始:
足球队只是一个足球运动员的名单。因此,我应该代表它:
var football_team = new List<FootballPlayer>();
此列表的顺序表示球员在名册中的顺序。
但后来我意识到,除了球员名单之外,球队还有其他的属性,这必须被记录下来。例如,本季度的总得分、当前预算、制服颜色、astring
代表团队的名称等
所以我想:
好吧,一支足球队就像一个球员名单,但除此之外,它还有一个名字(astring
)和一个连续的总分(int
)。NET不提供用于存储足球队的类,因此我将创建自己的类。最相似和最相关的现有结构是List<FootballPlayer>
因此,我将继承它:
class FootballTeam : List<FootballPlayer> {
public string TeamName;
public int RunningTotal }
但事实证明一条指南说你不应该继承List<T>
..在两个方面,我对这条准则感到十分困惑。
为什么不行?
显然List
在某种程度上优化了性能..怎么会这样?如果我扩展List
?到底会有什么突破?
我看到的另一个原因是List
是由微软提供的,我无法控制它,所以在公开了一个“公共API”之后,我不能稍后更改它。..但我很难理解。什么是公共API,我为什么要关心?如果我当前的项目没有并且很可能没有这个公共API,我能安全地忽略这个指南吗?如果我真的继承了List
和原来我需要一个公共API,我会遇到什么困难?
那又有什么关系呢?清单就是清单。有什么可以改变的?我能改变什么?
最后,如果微软不希望我继承List
,他们为什么不去上课sealed
?
我还能用什么?
显然,对于自定义集合,Microsoft提供了一个Collection
类,它应该被扩展,而不是List
..但是这门课很空旷,没有很多有用的东西,比如AddRange
例如。Jvitor 83的答复提供该特定方法的性能基本原理,但慢的是什么?AddRange
不比没有好AddRange
?
继承自Collection
是比继承更多的工作List
我看不出有什么好处。微软肯定不会无缘无故地告诉我要做额外的工作,所以我不禁觉得我误解了一些东西,并且继承了一些东西。Collection
其实不是解决我问题的正确办法。
我看到了一些建议,比如实现IList
..只是没有。这是几十行样板代码,没有给我带来任何好处。
最后,有人建议将List
在某件事上:
class FootballTeam {
public List<FootballPlayer> Players; }
这方面有两个问题:
它使我的代码不必要地冗长。我现在必须打电话my_team.Players.Count
而不是仅仅my_team.Count
..谢天谢地,使用C#,我可以定义索引器,使索引透明,并转发内部所有方法List
..但那是很多代码!我能从这些工作中得到什么?
很明显没有任何意义。一支足球队没有球员名单。它是球员名单。你不会说“约翰·麦克球员已经加入了SomeTeam的球员”。你说“约翰加入了SomeTeam”。您不向“字符串的字符”添加字母,而是向字符串中添加一个字母。你不把一本书加到图书馆的书里,而是把一本书加到图书馆里。
我意识到“引擎盖下”发生的事情可以说是“在Y的内部列表中添加X”,但这似乎是一种非常违背直觉的思考世界的方式。
我的问题(摘要)
什么是正确的C#表示数据结构的方式,它“逻辑上”(也就是说,“对人类的思维”)只是一个list
的things
有几个钟声和口哨?
是从List<T>
总是不能接受?什么时候可以接受?为什么/为什么不呢?程序员在决定是否从List<T>
还是不?