.jpg)
在规划我的程序时,我经常从这样的思路链开始:
足球队只是足球运动员的名单。因此,我应该用:
var football_team = new List<FootballPlayer>();此列表的顺序表示球员在名单中的列出顺序。
但后来我意识到,除了球员名单之外,球队还有其他属性必须记录。例如,本赛季的运行总得分,当前预算,统一颜色,代表球队名称的a等。string
所以我想:
好吧,一支足球队就像一个球员名单,但除此之外,它还有一个名字(a)和一个运行的总得分(一个)。.NET 不提供用于存储足球队的类,因此我将创建自己的类。最相似和最相关的现有结构是 ,所以我将从中继承:
stringintList<FootballPlayer>class FootballTeam : List<FootballPlayer> { public string TeamName; public int RunningTotal }
但事实证明,指南说你不应该从 .我在两个方面对这个指导方针感到非常困惑。List<T>
显然以某种方式针对性能进行了优化。怎么会这样?如果我扩展,会导致哪些性能问题?究竟什么会破裂?ListList
我看到的另一个原因是它是由微软提供的,我无法控制它,所以我以后在公开“公共 API”后无法更改它。但我很难理解这一点。什么是公共 API,我为什么要关心?如果我当前的项目没有也不太可能有这个公共 API,我可以安全地忽略这个准则吗?如果我确实继承了,结果证明我需要一个公共 API,我会有什么困难?ListList
为什么它甚至重要?列表就是列表。可能改变什么?我可能想要改变什么?
最后,如果微软不希望我继承,为什么他们不做这个类?Listsealed
显然,对于自定义集合,Microsoft 提供了一个应该扩展的类,而不是 .但是这个类非常光秃秃的,没有很多有用的东西,比如,例如。jvitor83 的答案为该特定方法提供了性能原理,但慢不如没有?CollectionListAddRangeAddRangeAddRange
继承自比继承自 要多得多,我认为没有任何好处。微软肯定不会无缘无故地告诉我做额外的工作,所以我不禁觉得我在某种程度上误解了什么,继承实际上不是解决我问题的正确方法。CollectionListCollection
我看到了诸如实施.只是没有。这是几十行样板代码,我一无所获。IList
最后,有些人建议将它包装在:List
class FootballTeam
{
public List<FootballPlayer> Players;
}
这有两个问题:
my_team.Players.Countmy_team.CountList我意识到“引擎盖下”发生的事情可以说是“将X添加到Y的内部列表中”,但这似乎是一种非常违反直觉的思考世界的方式。
表示数据结构的正确 C# 方法是什么,“逻辑上”(也就是说,“对人类的头脑”)只是一些花里胡哨的东西?listthings
继承总是不可接受的吗?什么时候可以接受?为什么/为什么不呢?程序员在决定是否继承时必须考虑什么?List<T>List<T>

网友回答:
哇,你的帖子有很多问题和观点。你从微软得到的大部分推理都是恰到好处的。让我们从一切开始List<T>
List<T> 高度优化。它的主要用途是用作对象的私有成员。class MyList<T, TX> : List<CustomObject<T, Something<TX>> { ... }var list = new MyList<int, string>();IList<T>Collection<T>SortedCollection<T>ObservableCollection<T>ReadOnlyCollection<T>IList<T>List<T>Collection<T>允许覆盖成员(即添加、删除等),因为它们是虚拟的。 不。List<T>如果我编写此代码,该类可能如下所示:
public class FootballTeam<T>//generic class
{
// Football team rosters are generally 53 total players.
private readonly List<T> _roster = new List<T>(53);
public IList<T> Roster
{
get { return _roster; }
}
// Yes. I used LINQ here. This is so I don't have to worry about
// _roster.Length vs _roster.Count vs anything else.
public int PlayerCount
{
get { return _roster.Count(); }
}
// Any additional members you want to expose/wrap.
}

网友回答:
这里有一些很好的答案。我要补充以下几点。
表示数据结构的正确 C# 方法是什么,“逻辑上”(也就是说,“对人类思维而言”)只是一个带有一些花里胡哨的东西列表?
请任意十个熟悉足球存在的非计算机程序员来填空:
足球队是一种特殊的____
有没有人说“有几个花里胡哨的足球运动员名单”,还是他们都说“运动队”或“俱乐部”或“组织”?你认为足球队是一种特殊的球员名单的想法在你的人类头脑中,而且只有你的人类头脑。
List<T>是一种机制。足球队是一个业务对象,即表示程序业务域中的某个概念的对象。不要混用这些!足球队是一种球队;它有一个名单,一个花名册是球员名单。名单不是一种特定的球员名单。名单是球员名单。因此,使一个名为 .当你在的时候去做,除非你相信每个了解足球队的人都可以从名单中删除球员。RosterList<Player>ReadOnlyList<Player>
继承总是不可接受的吗?
List<T>
谁不能接受?钥匙不。
什么时候可以接受?
构建扩展 List<T> 机制的机制时。
程序员在决定是否继承时必须考虑什么?
List<T>
我是在构建机制还是业务对象?
但这是很多代码!我能从所有这些工作中得到什么?
您花更多的时间键入您的问题,这需要您为相关成员编写五十次转发方法。你显然不怕冗长,我们在这里谈论的是很少的代码;这是几分钟的工作。List<T>
我考虑了一下,还有另一个原因不将足球队建模为球员名单。事实上,将一支足球队建模为拥有球员名单可能是一个坏主意。拥有球员名单的球队的问题在于,你得到的是球队在某个时刻的快照。我不知道你对这门课的商业案例是什么,但如果我有一个代表一支橄榄球队的班级,我会问它一些问题,比如“2003年至2013年间有多少海鹰队球员因伤缺席了比赛?”或者“以前为另一支球队效力的丹佛球员的码数同比增幅最大?”或者“猪队今年一路走来吗?”
也就是说,在我看来,一支足球队被很好地建模为历史事实的集合,例如球员何时被招募、受伤、退役等。显然,目前的球员名单是一个重要的事实,可能应该是最重要的,但你可能想用这个对象做其他有趣的事情,需要更历史的视角。

网友回答:
class FootballTeam : List<FootballPlayer>
{
public string TeamName;
public int RunningTotal;
}
以前的代码的意思是:一群街上的家伙在踢足球,他们碰巧有一个名字。像这样:
无论如何,这段代码(来自 m-y 的答案)
public class FootballTeam
{
// A team's name
public string TeamName;
// Football team rosters are generally 53 total players.
private readonly List<T> _roster = new List<T>(53);
public IList<T> Roster
{
get { return _roster; }
}
public int PlayerCount
{
get { return _roster.Count(); }
}
// Any additional members you want to expose/wrap.
}
模板简介:该模板名称为【为什么不从List