为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

浮云间 2019-06-03 15:28:36
为什么不继承列表<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>还是不?
查看完整描述

3 回答

?
白衣染霜花

TA贡献1796条经验 获得超10个赞

最后,一些人建议将列表包装在以下内容中:

这是正确的方法。“不必要的冗长”是一个不好的方式来看待这一点。当你写的时候,它有一个明确的含义。my_team.Players.Count..你想数球员。

my_team.Count

.毫无意义。数什么?

一支球队并不是一张名单-不仅仅是一张球员的名单。一支球队拥有球员,所以球员应该是它的一部分(一名成员)。

如果你真的由于担心过于冗长,您可以始终公开来自团队的属性:

public int PlayerCount {
    get {
        return Players.Count;
    }}

.这变成:

my_team.PlayerCount

这现在就有意义了,并依附于德米特定律.

您还应该考虑遵守复合再利用原理..通过继承List<T>你是说一个团队名单的球员和暴露不必要的方法从它。这是不正确的-正如你所说,一支球队不仅仅是一个球员的名单:它有一个名字,经理,董事会成员,教练,医务人员,工资帽等等。通过让你的团队类包含一个球员列表,你就是在说“一支球队有一个“球员名单”,但也可以有其他东西。


查看完整回答
反对 回复 2019-06-03
  • 3 回答
  • 0 关注
  • 492 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信