C# 如何将 List<T> 初始化为给定的大小(与容量相反)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/466946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to initialize a List<T> to a given size (as opposed to capacity)?
提问by Boaz
.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.
.NET 提供了一个通用列表容器,其性能几乎相同(请参阅数组与列表的性能问题)。然而,它们在初始化方面有很大的不同。
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);
or
或者
string[] Ar = new string[10];
List<string> L = new List<string>(Ar);
What would be a cleaner way?
什么是更清洁的方式?
EDIT: 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"
编辑:到目前为止的答案是指容量,这与预先填充列表不同。例如,在刚刚创建的容量为 10 的列表上,不能做L[2]="somevalue"
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:
编辑 2:人们想知道为什么我要以这种方式使用列表,因为这不是它们的预期使用方式。我可以看到两个原因:
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.
人们可以非常有说服力地争辩说列表是“下一代”数组,增加了灵活性,几乎没有任何损失。因此,默认情况下应该使用它们。我指出它们可能不那么容易初始化。
我目前正在编写的是一个基类,它提供默认功能作为更大框架的一部分。在我提供的默认功能中,列表的大小是预先知道的,因此我可以使用数组。但是,我想为任何基类提供动态扩展它的机会,因此我选择了一个列表。
采纳答案by Jon Skeet
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;
}
}
You coulduse Enumerable.Repeat(default(T), count).ToList()
but that would be inefficient due to buffer resizing.
您可以使用Enumerable.Repeat(default(T), count).ToList()
但由于缓冲区大小调整而效率低下。
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.
请注意,如果T
是引用类型,它将存储count
为value
参数传递的引用的副本- 因此它们都将引用同一个对象。这可能是您想要的,也可能不是,这取决于您的用例。
EDIT: 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.
编辑:如评论中所述,如果需要,您可以Repeated
使用循环来填充列表。那也会稍微快一点。我个人认为代码使用Repeat
更具描述性,并怀疑在现实世界中性能差异无关紧要,但您的里程可能会有所不同。
回答by Ed S.
Use the constructor which takes an int ("capacity") as an argument:
使用以 int ("capacity") 作为参数的构造函数:
List<string> = new List<string>(10);
EDIT: I should add that I agree with Frederik. You are using the List in a way that goes against the entire reasoning behind using it in the first place.
编辑:我应该补充一点,我同意弗雷德里克的观点。您使用 List 的方式与首先使用它的整个推理背道而驰。
EDIT2:
编辑2:
EDIT 2: 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.
编辑 2:我目前正在编写的是一个基类,它提供默认功能作为更大框架的一部分。在我提供的默认功能中,列表的大小是预先知道的,因此我可以使用数组。但是,我想为任何基类提供动态扩展它的机会,因此我选择了一个列表。
Why would anyone need to know the size of a List with all null values? If there are no real values in the list, I would expect the length to be 0. Anyhow, the fact that this is cludgy demonstrates that it is going against the intended use of the class.
为什么有人需要知道包含所有空值的 List 的大小?如果列表中没有实际值,我希望长度为 0。无论如何,这很笨拙的事实表明它违背了类的预期用途。
回答by Frederik Gheysels
Why are you using a List if you want to initialize it with a fixed value ? I can understand that -for the sake of performance- you want to give it an initial capacity, but isn't one of the advantages of a list over a regular array that it can grow when needed ?
如果要使用固定值初始化它,为什么要使用 List ?我可以理解——为了性能——你想给它一个初始容量,但是列表相对于它可以在需要时增长的常规数组的优势之一不是吗?
When you do this:
当你这样做时:
List<int> = new List<int>(100);
You create a list whose capacity is 100 integers. This means that your List won't need to 'grow' until you add the 101th item. The underlying array of the list will be initialized with a length of 100.
您创建了一个容量为 100 个整数的列表。这意味着在添加第 101 项之前,您的列表不需要“增长”。列表的底层数组将被初始化为 100 的长度。
回答by Welbog
Initializing the contents of a list like that isn't really what lists are for. Lists are designed to hold objects. If you want to map particular numbers to particular objects, consider using a key-value pair structure like a hash table or dictionary instead of a list.
像这样初始化列表的内容并不是列表的真正用途。列表旨在保存对象。如果要将特定数字映射到特定对象,请考虑使用键值对结构(如哈希表或字典)而不是列表。
回答by Henk
string [] temp = new string[] {"1","2","3"};
List<string> temp2 = temp.ToList();
回答by Amy B
If you want to initialize the list with N elements of some fixed value:
如果你想用 N 个固定值的元素初始化列表:
public List<T> InitList<T>(int count, T initValue)
{
return Enumerable.Repeat(initValue, count).ToList();
}
回答by Greg D
You seem to be emphasizing the need for a positional association with your data, so wouldn't an associative array be more fitting?
您似乎强调需要与您的数据进行位置关联,那么关联数组不是更合适吗?
Dictionary<int, string> foo = new Dictionary<int, string>();
foo[2] = "string";
回答by Greg D
List<string> L = new List<string> ( new string[10] );
回答by James Lawruk
You can use Linq to cleverly initialize your list with a default value. (Similar to David B's answer.)
您可以使用 Linq 巧妙地使用默认值初始化您的列表。(类似于大卫 B 的回答。)
var defaultStrings = (new int[10]).Select(x => "my value").ToList();
Go one step farther and initialize each string with distinct values "string 1", "string 2", "string 3", etc:
再进一步,用不同的值“字符串 1”、“字符串 2”、“字符串 3”等初始化每个字符串:
int x = 1;
var numberedStrings = (new int[10]).Select(x => "string " + x++).ToList();
回答by mini998
Create an array with the number of items you want first and then convert the array in to a List.
首先创建一个包含您想要的项目数的数组,然后将该数组转换为列表。
int[] fakeArray = new int[10];
List<int> list = fakeArray.ToList();