C# 如何初始化列表<;T>;到给定的大小(相对于容量)?
.NET提供了一个性能几乎相同的通用列表容器(请参阅数组性能与列表问题)。但是,它们在初始化方面有很大的不同 数组很容易用默认值初始化,根据定义,它们已经具有一定的大小:C# 如何初始化列表<;T>;到给定的大小(相对于容量)?,c#,.net,generics,list,initialization,C#,.net,Generics,List,Initialization,.NET提供了一个性能几乎相同的通用列表容器(请参阅数组性能与列表问题)。但是,它们在初始化方面有很大的不同 数组很容易用默认值初始化,根据定义,它们已经具有一定的大小: string[] Ar = new string[10]; 这样就可以安全地分配随机项目,比如: Ar[5]="hello"; 有了清单,事情就更棘手了。我可以看到两种方法进行相同的初始化,这两种方法都不是您所说的优雅: List<string> L = new List<string>(10);
string[] Ar = new string[10];
这样就可以安全地分配随机项目,比如:
Ar[5]="hello";
有了清单,事情就更棘手了。我可以看到两种方法进行相同的初始化,这两种方法都不是您所说的优雅:
List<string> L = new List<string>(10);
for (int i=0;i<10;i++) L.Add(null);
List L=新列表(10);
对于(int i=0;i使用以int(“容量”)为参数的构造函数:
List<string> = new List<string>(10);
List=新列表(10);
编辑:我应该补充一点,我同意弗雷德里克的观点。你使用这个列表的方式违背了最初使用它的全部理由
编辑2:
编辑2:我目前正在编写的是一个基类,它作为更大框架的一部分提供默认功能。在我提供的默认功能中,列表的大小在高级中是已知的,因此我可以使用数组。但是,我希望为任何基类提供动态扩展它的机会,因此我选择列表
为什么任何人都需要知道一个包含所有空值的列表的大小?如果列表中没有实际值,我希望长度为0。无论如何,这是一个模糊的事实表明它违背了类的预期用途。如果要用固定值初始化列表,为什么要使用列表?
我可以理解,为了性能起见,您希望给它一个初始容量,但与常规阵列相比,列表的优点之一不是可以在需要时增长吗
执行此操作时:
List<int> = new List<int>(100);
List=新列表(100);
您创建了一个容量为100个整数的列表。这意味着您的列表在添加第101项之前不需要“增长”。
列表的基础数组将以100的长度初始化。< p>初始化列表的内容并不是列表所用的。列表是用来保存对象的。如果要将特定的数字映射到特定对象,请考虑使用像哈希表或字典之类的键值对结构,而不是列表。我不能说我经常需要它-您能详细说明为什么需要它吗?我可能会将它作为一个静态方法放在helper类中:
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;
}
}
公共静态类列表
{
公共静态列表RepeatedDefault(整数计数)
{
重复返回(默认值(T),计数);
}
公共静态列表重复(T值,int计数)
{
List ret=新列表(计数);
ret.AddRange(可枚举.重复(值,计数));
返回ret;
}
}
您可以使用Enumerable.Repeat(默认值(T),count).ToList()
,但由于缓冲区大小的调整,这样做效率低下
注意,如果T
是引用类型,它将存储count
为value
参数传递的引用副本,因此它们都将引用相同的对象。这可能是您想要的,也可能不是,取决于您的用例
编辑:如注释中所述,如果愿意,您可以使用循环来填充列表。这也会稍微快一点。我个人认为使用重复的代码更具描述性,并且怀疑在现实世界中性能差异无关紧要,但您的里程数可能会有所不同。string[]临时=新字符串[]{“1”、“2”、“3”};
string [] temp = new string[] {"1","2","3"};
List<string> temp2 = temp.ToList();
List temp2=临时ToList();
如果要使用某些固定值的N个元素初始化列表:
public List<T> InitList<T>(int count, T initValue)
{
return Enumerable.Repeat(initValue, count).ToList();
}
public List InitList(int count,T initValue)
{
返回可枚举的.Repeat(initValue,count).ToList();
}
您似乎在强调需要与数据建立位置关联,因此关联数组不是更合适吗
Dictionary<int, string> foo = new Dictionary<int, string>();
foo[2] = "string";
Dictionary foo=newdictionary();
foo[2]=“字符串”;
List L=新列表(新字符串[10]);
您可以使用Linq巧妙地用默认值初始化列表。(类似于。)
更进一步,用不同的值“字符串1”、“字符串2”、“字符串3”等初始化每个字符串:
首先创建一个包含所需项数的数组,然后将该数组转换为列表
int[] fakeArray = new int[10];
List<int> list = fakeArray.ToList();
int[]fakeArray=newint[10];
List=fakeArray.ToList();
关于IList的通知:
:
IList实现分为三类:只读、固定大小和可变大小。(…)。有关此接口的通用版本,请参阅
System.Collections.Generic.IList
”
IList
不继承自IList
(但是List
实现了IList
和IList
),但始终是。
从.NET 4.5开始,我们也创建了IReadOnlyList
,但现在还没有固定大小的通用列表,您需要的就是它。这是我在单元测试中使用的一个示例。我创建了一个类对象列表。然后我使用forloop添加了“X”个我期望从服务中得到的对象。
通过这种方式,您可以添加/初始化任何给定大小的列表
public void TestMethod1()
{
var expected = new List<DotaViewer.Interface.DotaHero>();
for (int i = 0; i < 22; i++)//You add empty initialization here
{
var temp = new DotaViewer.Interface.DotaHero();
expected.Add(temp);
}
var nw = new DotaHeroCsvService();
var items = nw.GetHero();
CollectionAssert.AreEqual(expected,items);
}
public void TestMethod1()
{
var expected=新列表();
对于(int i=0;i<22;i++)//在此处添加空初始化
{
var temp=new DotaViewer.Interface.DotaHero();
预期。添加(临时);
}
var nw=新的DotaHeroCsvService();
var items=nw.GetHero();
收款资产等于(预计,项目);
}
希望我能对你们有所帮助。有点晚了,但你们提出的第一个解决方案对我来说似乎更干净:你们不会分配两次内存。
即使是列表构造函数也需要循环遍历数组才能复制它;它甚至事先都不知道数组中只有空元素
一,。
-分配
-环路N
成本:1*分配(N)+N*循环
var defaultStrings = (new int[10]).Select(x => "my value").ToList();
int x = 1;
var numberedStrings = (new int[10]).Select(x => "string " + x++).ToList();
int[] fakeArray = new int[10];
List<int> list = fakeArray.ToList();
public void TestMethod1()
{
var expected = new List<DotaViewer.Interface.DotaHero>();
for (int i = 0; i < 22; i++)//You add empty initialization here
{
var temp = new DotaViewer.Interface.DotaHero();
expected.Add(temp);
}
var nw = new DotaHeroCsvService();
var items = nw.GetHero();
CollectionAssert.AreEqual(expected,items);
}
var result = Lists.Repeated(new MyType(), sizeOfList);
// each item in the list references the same MyType() object
// if you edit item 1 in the list, you are also editing item 2 in the list
public static List<T> RepeatedDefaultInstance<T>(int count)
{
List<T> ret = new List<T>(count);
for (var i = 0; i < count; i++)
{
ret.Add((T)Activator.CreateInstance(typeof(T)));
}
return ret;
}
public static List<T> NewOfSize<T>(int size) {
var list = new List<T>(size);
var sizeField = list.GetType().GetField("_size",BindingFlags.Instance|BindingFlags.NonPublic);
sizeField.SetValue(list, size);
return list;
}