在规划我的计划时,我通常会从这样的一系列想法开始:
足球队就是足球运动员的名单。因此,我应该用以下方式来表示:
var football\u team=新列表<;足球运动员>;();这份名单的顺序代表了球员在名册上的排列顺序
但我后来意识到,除了球员名单之外,球队还有其他必须记录的属性。例如,本赛季的总成绩、当前预算、统一颜色、代表球队名称的字符串等
所以我想:
好的,足球队就像一张球员名单,但除此之外,它还有一个名字(一个
字符串)和一个总得分(一个int)。NET不提供用于存储足球队的类,因此我将创建自己的类。最相似和最相关的现有结构是List<;足球运动员>,因此我将从中继承:职业足球队:名单<;足球运动员>; { 公共字符串组名; 公共整数运行总计 }
但事实证明,一条指导方针说,您不应该从List<;T>。我完全被这条指导方针搞糊涂了
为什么不呢
显然,List以某种方式优化了性能。为什么呢如果扩展列表,会导致哪些性能问题?到底什么东西会断裂
我看到的另一个原因是List是由微软提供的,我对它没有控制权,所以在公开了“公共API”之后,我以后无法更改它。但我很难理解这一点。什么是公共API?我为什么要关心它?如果我当前的项目没有也不可能有这个公共API,我可以安全地忽略这个指南吗?如果我确实继承了列表并且发现我需要一个公共API,那么我会遇到什么困难
为什么这很重要?清单就是清单。有什么可能改变?我可能想要改变什么
最后,如果微软不想让我继承列表,为什么他们不让类密封
我还能用什么
显然,对于自定义集合,Microsoft提供了一个集合类,该类应该扩展,而不是列表。但是这个类非常简单,没有很多有用的东西,例如AddRange。jvitor83的回答提供了该特定方法的性能原理,但是缓慢的AddRange如何不比没有AddRange好呢
从集合继承要比从列表继承多得多,我看不出有什么好处。当然,微软不会无缘无故地告诉我做额外的工作,所以我忍不住觉得自己在某种程度上误解了什么,而继承集合实际上并不是解决我问题的正确方法
我看到了一些建议,比如实现IList。只是没有。这是几十行的样板代码,我什么也得不到
最后,一些人建议将列表包装成以下内容:
职业足球队
{
公开名单<;足球运动员>;球员;
}
这有两个问题:
-
它使我的代码变得不必要的冗长。我现在必须调用
我的团队.Players.Count而不是我的团队.Count。谢天谢地,有了C#我可以定义索引器使索引透明,并转发内部列表的所有方法。。。但这是很多代码!那些工作我能得到什么 -
这显然没有任何意义。足球队没有球员名单。这是球员名单。你不会说“约翰·麦克斯波尔加入了某支球队的球员”。你说“约翰加入了某个团队”。您不会在“字符串的字符”中添加字母,而是在字符串中添加字母。你不是在图书馆的书中添加一本书,而是在图书馆中添加一本书
我意识到“在引擎盖下”发生的事情可以说是“在Y的内部列表中添加X”,但这似乎是一种非常违反直觉的思考世界的方式
我的问题(摘要)
正确的C#表示数据结构的方式是什么,“逻辑上”(也就是说,“对人的头脑来说”)只是一个列表,包含事物,只需几声钟声和口哨
继承自列表<;T>总是不可接受?什么时候可以接受?为什么?程序员在决定是否继承列表>时,必须考虑什么?T>还是不
这里有一些很好的答案。我想补充以下几点
正确的C#表示数据结构的方式是什么,“逻辑上”(也就是说,“对人类思维而言”)只是一个带有一些铃铛和口哨的事物列表
请任何十位熟悉足球存在的非计算机程序员填写以下空白:
足球队是一种特殊的运动_____
有没有人说“带着一些铃铛和口哨的足球运动员名单”,或者他们都说“运动队”或“俱乐部”或“组织”?你认为一支足球队是一种特殊的球员名单,这种想法存在于你的人类思维中,也仅存在于你的人类思维中
列表<;T>是一种机制。足球队是一个业务对象——也就是说,一个代表项目业务领域中某些概念的对象。别把它们混在一起!足球队是一种球队;它有一个花名册,花名册是一个球员名单。花名册不是一个特定类型的球员名单。花名册是球员名单。因此,创建一个名为花名册的属性,它是一个列表<;播放器>。并使其ReadOnlyList<;播放器>当你这样做的时候,除非你相信每个了解足球队的人都可以从名单中删除球员
继承自
列表<;T>总是不可接受
谁不能接受?我没有
什么时候可以接受
当您正在构建一个扩展列表的机制时<;T>机构
当程序员决定是否从列表中继承时,程序员必须考虑什么?T>还是不
我是在构建一个机制还是一个业务对象
但这是很多代码!那些工作我能得到什么
您花了更多的时间输入您的问题,这将花费您为List<;的相关成员编写转发方法;T>50次以上。很明显,您并不害怕冗长,我们在这里讨论的是非常少量的代码;这是几分钟的工作
更新
我对此进行了更多的思考,还有另一个理由不将足球队作为球员名单来建模。事实上,将一支足球队建模为同时拥有一份球员名单可能不是一个好主意。有球员名单的球队的问题在于,你得到的是球队在某一时刻的快照。我不知道你在这门课上的商业案例是什么,但如果我有一门代表足球队的课,我想问一些问题,比如“在2003年到2013年间,有多少海鹰队的球员因为伤病错过了比赛?”或者“之前为另一支球队效力的丹佛队球员的跑位同比增长最大?”“今年猪圈走到哪里去了?”
也就是说,在我看来,足球队似乎是一个历史事实的集合,例如球员被招募、受伤、退役等。显然,当前的球员名册是一个重要的事实,可能是最重要的事实,但可能还有其他有趣的事情需要你来处理更具历史意义的观点