猿问

为什么不继承列表<T>?

为什么不继承列表<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; }

这方面有两个问题:

  1. 它使我的代码不必要地冗长。我现在必须打电话my_team.Players.Count而不是仅仅my_team.Count..谢天谢地,使用C#,我可以定义索引器,使索引透明,并转发内部所有方法List..但那是很多代码!我能从这些工作中得到什么?

  2. 很明显没有任何意义。一支足球队没有球员名单。它球员名单。你不会说“约翰·麦克球员已经加入了SomeTeam的球员”。你说“约翰加入了SomeTeam”。您不向“字符串的字符”添加字母,而是向字符串中添加一个字母。你不把一本书加到图书馆的书里,而是把一本书加到图书馆里。

我意识到“引擎盖下”发生的事情可以说是“在Y的内部列表中添加X”,但这似乎是一种非常违背直觉的思考世界的方式。

我的问题(摘要)

什么是正确的C#表示数据结构的方式,它“逻辑上”(也就是说,“对人类的思维”)只是一个listthings有几个钟声和口哨?

是从List<T>总是不能接受?什么时候可以接受?为什么/为什么不呢?程序员在决定是否从List<T>还是不?


浮云间
浏览 493回答 3
3回答

白衣染霜花

最后,一些人建议将列表包装在以下内容中:这是正确的方法。“不必要的冗长”是一个不好的方式来看待这一点。当你写的时候,它有一个明确的含义。my_team.Players.Count..你想数球员。my_team.Count.毫无意义。数什么?一支球队并不是一张名单-不仅仅是一张球员的名单。一支球队拥有球员,所以球员应该是它的一部分(一名成员)。如果你真的由于担心过于冗长,您可以始终公开来自团队的属性:public&nbsp;int&nbsp;PlayerCount&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;get&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Players.Count; &nbsp;&nbsp;&nbsp;&nbsp;}}.这变成:my_team.PlayerCount这现在就有意义了,并依附于德米特定律.您还应该考虑遵守复合再利用原理..通过继承List<T>你是说一个团队是名单的球员和暴露不必要的方法从它。这是不正确的-正如你所说,一支球队不仅仅是一个球员的名单:它有一个名字,经理,董事会成员,教练,医务人员,工资帽等等。通过让你的团队类包含一个球员列表,你就是在说“一支球队有一个“球员名单”,但也可以有其他东西。
随时随地看视频慕课网APP
我要回答