首页 > C# > 为什么不从List继承?

为什么不从List继承?

上一篇 下一篇

在规划我的程序时,我经常从这样的思路链开始:

足球队只是足球运动员的名单。因此,我应该用:

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; 
}

这有两个问题:

  1. 它使我的代码不必要地冗长。我现在必须打电话,而不仅仅是.值得庆幸的是,使用 C#,我可以定义索引器以使索引透明,并转发内部的所有方法……但这是很多代码!我能从所有这些工作中得到什么?my_team.Players.Countmy_team.CountList
  2. 这显然没有任何意义。足球队没有“有”球员名单。这是玩家名单。你不会说“John McFootballer加入了SomeTeam的球员”。你说“约翰加入了SomeTeam”。您不是在“字符串的字符”中添加字母,而是向字符串添加字母。您不是将一本书添加到图书馆的书籍中,而是将一本书添加到图书馆。

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

我的问题(摘要)

表示数据结构的正确 C# 方法是什么,“逻辑上”(也就是说,“对人类的头脑”)只是一些花里胡哨的东西?listthings

继承总是不可接受的吗?什么时候可以接受?为什么/为什么不呢?程序员在决定是否继承时必须考虑什么?List<T>List<T>
分割线

网友回答:

哇,你的帖子有很多问题和观点。你从微软得到的大部分推理都是恰到好处的。让我们从一切开始List<T>

  • List<T> 高度优化。它的主要用途是用作对象的私有成员。
  • Microsoft 没有密封它,因为有时您可能希望创建一个名称更友好的类:。现在就像做一样简单.class MyList<T, TX> : List<CustomObject<T, Something<TX>> { ... }var list = new MyList<int, string>();
  • CA1002:不要公开泛型列表:基本上,即使您打算将此应用程序用作唯一的开发人员,也值得使用良好的编码实践进行开发,因此它们会灌输给您和第二天性。如果需要任何使用者拥有索引列表,您仍然可以将列表公开为 。这使您可以稍后更改类中的实现。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继承?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 282次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 02-10
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
自适应 微信公众平台 html5 企业网站 单页式简历模板 微信图片 响应式 微信素材 微信文章 微信模板
您可能会喜欢的其他模板