在计划程序时,我通常会像这样思考:
足球队只是足球运动员的名单。因此,我应该用:
var football_team = new List<FootballPlayer>();
该列表的顺序代表了球员在名单中的排列顺序。
但是后来我意识到,除了仅列出球员名单以外,球队还具有其他属性,必须加以记录。例如,本赛季的总得分,当前预算,统一的颜色,string
代表球队名称的a 等。
所以我想:
好的,足球队就像一个球员名单,但另外,它还有一个名称(a
string
)和一个总得分(anint
)。.NET没有提供用于存储足球队的课程,因此我将创建自己的课程。最相似,最相关的现有结构是List<FootballPlayer>
,因此我将从中继承:class FootballTeam : List<FootballPlayer> { public string TeamName; public int RunningTotal }
但事实证明,指南指出您不应继承List<T>
。我对该指南在两个方面完全感到困惑。
为什么不?
显然List
在某种程度上针对性能进行了优化。为何如此?如果我扩展,会导致什么性能问题List
?到底会破裂什么?
我看到的另一个原因List
是Microsoft提供的,并且我无法控制它,因此在公开“公共API”之后,以后不能更改它。但是我很难理解这一点。什么是公共API,我为什么要关心?如果我当前的项目没有并且不太可能拥有此公共API,那么我可以安全地忽略此指南吗?如果我确实继承自我,List
而事实证明我需要一个公共API,我会遇到什么困难?
为什么如此重要?列表就是列表。有什么可能改变?我可能要更改什么?
最后,如果Microsoft不希望我从那里继承List
,他们为什么不上课sealed
?
我还应该使用什么?
显然,对于自定义集合,Microsoft提供了一个Collection
应该扩展而不是的类List
。但这个类是非常裸露,并没有多少有用的东西,比如AddRange
,例如。jvitor83的答案提供了该特定方法的性能原理,但是慢AddRange
不是没有总比没有更好AddRange
?
从Collection
继承比从继承进行的工作量更大List
,我看不出任何好处。毫无疑问,Microsoft不会无缘无故地告诉我做额外的工作,所以我不禁会觉得自己在某种程度上误解了某些东西,而继承Collection
实际上并不是解决我的问题的正确方法。
我已经看到了诸如实施的建议IList
。就是不行。这是几十行样板代码,对我毫无帮助。
最后,有些人建议将包裹起来List
:
class FootballTeam
{
public List<FootballPlayer> Players;
}
这有两个问题:
它使我的代码不必要地冗长。我现在必须打电话,
my_team.Players.Count
而不仅仅是my_team.Count
。幸运的是,使用C#,我可以定义索引器以使索引透明化,并转发内部的所有方法List
……但这就是很多代码!我能从所有工作中得到什么?只是没有任何意义。一支足球队没有“拥有”球员名单。这是球员名单。您不会说“ John McFootballer已加入SomeTeam的球员”。您说“约翰加入了SomeTeam”。您没有在“字符串的字符”中添加字母,而是在字符串中添加了字母。您没有将书添加到图书馆的书中,而是将书添加到图书馆。
我意识到,“幕后”发生的事情可以说是“将X添加到Y的内部列表中”,但是这似乎是一种非常违反直觉的思维方式。
我的问题(总结)
什么是代表一个数据结构,其中,“逻辑”(即,“以人的心灵”)仅仅是一个正确的C#这样list
的things
与一些花俏?
从List<T>
永远继承是不可接受的吗?什么时候可以接受?为什么/为什么不呢?程序员在决定是否继承时必须考虑什么List<T>
?
string
需要A 做所有object
可以做的事以及更多。