Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何初始化列表<;T>;到给定的大小(相对于容量)?_C#_.net_Generics_List_Initialization - Fatal编程技术网

C# 如何初始化列表<;T>;到给定的大小(相对于容量)?

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

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

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

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