如何初始化 List<T>到给定的大小(与容量相反)? [英] How to initialize a List&lt;T&gt; to a given size (as opposed to capacity)?

查看:25
本文介绍了如何初始化 List<T>到给定的大小(与容量相反)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.NET 提供了一个性能几乎相同的通用列表容器(请参阅数组与列表的性能问题).然而,它们在初始化方面有很大的不同.

.NET offers a generic list container whose performance is almost identical (see Performance of Arrays vs. Lists question). However they are quite different in initialization.

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

Arrays are very easy to initialize with a default value, and by definition they already have certain size:

string[] Ar = new string[10];

允许安全地分配随机项目,例如:

Which allows one to safely assign random items, say:

Ar[5]="hello";

使用列表更棘手.我可以看到两种执行相同初始化的方法,这两种方法都不是您所说的优雅:

with list things are more tricky. I can see two ways of doing the same initialization, neither of which is what you would call elegant:

List<string> L = new List<string>(10);
for (int i=0;i<10;i++) L.Add(null);

string[] Ar = new string[10];
List<string> L = new List<string>(Ar);

什么是更清洁的方法?

到目前为止的答案是指容量,这与预先填充列表不同.例如,在刚创建的容量为 10 的列表上,不能执行 L[2]="somevalue"

The answers so far refer to capacity, which is something else than pre-populating a list. For example, on a list just created with a capacity of 10, one cannot do L[2]="somevalue"

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

EDIT 2: People wonder why I want to use lists this way, as it is not the way they are intended to be used. I can see two reasons:

  1. 人们可以非常有说服力地争辩说列表是下一代"数组,增加了灵活性,几乎没有任何损失.因此,默认情况下应该使用它们.我要指出的是,它们可能没有那么容易初始化.

  1. One could quite convincingly argue that lists are the "next generation" arrays, adding flexibility with almost no penalty. Therefore one should use them by default. I'm pointing out they might not be as easy to initialize.

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

What I'm currently writing is a base class offering default functionality as part of a bigger framework. In the default functionality I offer, the size of the List is known in advanced and therefore I could have used an array. However, I want to offer any base class the chance to dynamically extend it and therefore I opt for a list.

推荐答案

我不能说我经常需要这个 - 你能详细说明你为什么想要这个吗?我可能会把它作为一个辅助类中的静态方法:

I can't say I need this very often - could you give more details as to why you want this? I'd probably put it as a static method in a helper class:

public static class Lists
{
    public static List<T> RepeatedDefault<T>(int count)
    {
        return Repeated(default(T), count);
    }

    public static List<T> Repeated<T>(T value, int count)
    {
        List<T> ret = new List<T>(count);
        ret.AddRange(Enumerable.Repeat(value, count));
        return ret;
    }
}

可以使用Enumerable.Repeat(default(T), count).ToList(),但由于缓冲区大小调整,效率低下.

You could use Enumerable.Repeat(default(T), count).ToList() but that would be inefficient due to buffer resizing.

请注意,如果 T 是引用类型,它将存储为 value 参数传递的引用的 count 个副本 - 因此它们将都指向同一个对象.这可能是也可能不是您想要的,具体取决于您的用例.

Note that if T is a reference type, it will store count copies of the reference passed for the value parameter - so they will all refer to the same object. That may or may not be what you want, depending on your use case.

如评论中所述,如果您愿意,您可以让 Repeated 使用循环来填充列表.那也会稍微快一点.我个人认为使用 Repeat 的代码更具描述性,并怀疑在现实世界中性能差异无关紧要,但您的里程可能会有所不同.

As noted in comments, you could make Repeated use a loop to populate the list if you wanted to. That would be slightly faster too. Personally I find the code using Repeat more descriptive, and suspect that in the real world the performance difference would be irrelevant, but your mileage may vary.

这篇关于如何初始化 List<T>到给定的大小(与容量相反)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆