相关疑难解决方法(0)

为什么不从List <T>继承?

在规划我的程序时,我经常从一连串的想法开始:

足球队只是一个足球运动员名单.因此,我应该代表它:

var football_team = new List<FootballPlayer>();
Run Code Online (Sandbox Code Playgroud)

此列表的顺序表示球员在名单中列出的顺序.

但我后来才意识到,除了仅仅是球员名单之外,球队还有其他属性,必须记录下来.例如,本赛季的总得分,当前预算,统一颜色,string代表球队名称等等.

那么我认为:

好吧,足球队就像一个球员名单,但另外,它有一个名称(a string)和一个总分(a int)..NET不提供用于存储足球队的类,所以我将创建自己的类.最相似和相关的现有结构是List<FootballPlayer>,所以我将继承它:

class FootballTeam : List<FootballPlayer> 
{ 
    public string TeamName; 
    public int RunningTotal 
}
Run Code Online (Sandbox Code Playgroud)

但事实证明,指南说你不应该继承List<T>.我在两个方面完全被这个指南搞糊涂了.

为什么不?

显然List是以某种方式针对性能进行了优化.怎么会这样?如果我延长会给我带来什么性能问题List?究竟会打破什么?

我看到的另一个原因List是微软提供的,我无法控制它,所以我在以后暴露"公共API"后无法改变它.但我很难理解这一点.什么是公共API,我为什么要关心?如果我当前的项目没有并且不太可能拥有此公共API,我可以放心地忽略此指南吗?如果我继承List 并且事实证明我需要一个公共API,那么我将遇到什么困难?

为什么它甚至重要?列表是一个列表.什么可能改变?我可能想要改变什么?

最后,如果微软不想让我继承List,他们为什么不上课sealed呢?

我还应该使用什么呢?

显然,对于自定义集合,Microsoft提供了一个Collection应该扩展的类而不是List.但这个类是非常裸露,并没有多少有用的东西,比如AddRange,例如.jvitor83的答案提供了该特定方法的性能原理,但是如何缓慢AddRange而不是没有AddRange

继承Collection是比继承更多的工作List,我认为没有任何好处.当然微软不会告诉我无缘无故地做额外的工作,所以我不禁觉得我在某种程度上误解了某些东西,而继承Collection实际上并不是解决我问题的正确方法.

我见过如实施的建议IList …

.net c# oop inheritance list

1299
推荐指数
22
解决办法
17万
查看次数

如何将List <T>初始化为给定大小(而不是容量)?

.NET提供了一个通用列表容器,其性能几乎相同(请参阅阵列性能与列表问题).但是它们在初始化方面完全不同.

使用默认值很容易初始化数组,根据定义,它们已经具有一定的大小:

string[] Ar = new string[10];
Run Code Online (Sandbox Code Playgroud)

这允许人们安全地分配随机项目,比如说:

Ar[5]="hello";
Run Code Online (Sandbox Code Playgroud)

列表事情更棘手.我可以看到两种方法进行相同的初始化,这两种方式都不是你所谓的优雅:

List<string> L = new List<string>(10);
for (int i=0;i<10;i++) L.Add(null);
Run Code Online (Sandbox Code Playgroud)

要么

string[] Ar = new string[10];
List<string> L = new List<string>(Ar);
Run Code Online (Sandbox Code Playgroud)

什么是更干净的方式?

编辑:到目前为止的答案是指容量,这不是预先填充列表.例如,在刚创建的容量为10的列表中,无法做到L[2]="somevalue"

编辑2:人们想知道为什么我想以这种方式使用列表,因为它不是他们打算使用的方式.我可以看到两个原因:

  1. 人们可以非常有说服力地认为列表是"下一代"阵列,增加灵活性几乎不会受到惩罚.因此,默认情况下应该使用它们.我指出它们可能不那么容易初始化.

  2. 我目前正在编写的是一个基类,它提供默认功能作为更大框架的一部分.在我提供的默认功能中,List的大小在高级中是已知的,因此我可以使用数组.但是,我想为任何基类提供动态扩展它的机会,因此我选择了一个列表.

.net c# generics initialization list

99
推荐指数
9
解决办法
17万
查看次数

以C#/最快的方式实现稀疏数组,将整数映射到特定的桶/范围号

我最初的问题是我需要在C#中实现一个非常快速的稀疏数组.最初的想法是使用法线Dictionary<uint, TValue>并将其包装在我自己的类中以仅显示TValue类型参数.事实证明这很慢.

所以我的下一个想法是将所需范围(UInt32.MinValueto UInt32.MaxValue)中的每个整数映射到某个大小的存储桶并使用它.所以我正在寻找一种将无符号整数X映射到桶Y的好方法,例如:

将数字0-1023映射到8个不同的桶,每个桶包含128个数字,0-127,128-255.

但是,如果某人有更好的方法在C#中实现快速稀疏数组,那么这也是最受欢迎的.

c# algorithm

11
推荐指数
2
解决办法
1万
查看次数

标签 统计

c# ×3

.net ×2

list ×2

algorithm ×1

generics ×1

inheritance ×1

initialization ×1

oop ×1