如何动态设置c#中的数组长度

我还是C#的新手,我一直在努力解决arrays上的各种问题。 我有一组元数据对象(名称值对),我想知道如何只创建我真正需要的“InputProperty”对象的数量。 在这个循环中,我任意设置元素的数量为20,当条目变为null时我试图挽救但是接收端的Web服务不喜欢传递给它的任何null元素:

private Update BuildMetaData(MetaData[] nvPairs) { Update update = new Update(); InputProperty[] ip = new InputProperty[20]; // how to make this "dynamic" int i; for (i = 0; i < nvPairs.Length; i++) { if (nvPairs[i] == null) break; ip[i] = new InputProperty(); ip[i].Name = "udf:" + nvPairs[i].Name; ip[i].Val = nvPairs[i].Value; } update.Items = ip; return update; } 

总之,假设我在上面的输入数组中只有3个名值对? 而不是为名为ip的数组分配20个元素,如何编写代码,以便ip只需要它所需的大小。 更新对象通过另一个Web服务传递,因此序列化很重要(即我不能使用namevaluecollection等)。

ps是通过“添加评论”工具跟踪发布的问题的唯一方法吗?

如果您不想使用ListArrayList或其他动态大小的集合然后转换为数组(顺便说一句,这是我推荐的方法),那么您必须将数组分配给它最大可能的大小,跟踪您放入的项目数量,然后创建一个新数组,其中只包含其中的项目:

 private Update BuildMetaData(MetaData[] nvPairs) { Update update = new Update(); InputProperty[] ip = new InputProperty[20]; // how to make this "dynamic" int i; for (i = 0; i < nvPairs.Length; i++) { if (nvPairs[i] == null) break; ip[i] = new InputProperty(); ip[i].Name = "udf:" + nvPairs[i].Name; ip[i].Val = nvPairs[i].Value; } if (i < nvPairs.Length) { // Create new, smaller, array to hold the items we processed. update.Items = new InputProperty[i]; Array.Copy(ip, update.Items, i); } else { update.Items = ip; } return update; } 

另一种方法是始终分配update.Items = ip; 然后在必要时resize:

 update.Items = ip; if (i < nvPairs.Length) { Array.Resize(update.Items, i); } 

它的代码较少,但最终可能会完成相同的工作量(即创建一个新数组并复制旧项目)。

 InputProperty[] ip = new InputProperty[nvPairs.Length]; 

或者,您可以使用如下列表:

 List list = new List(); InputProperty ip = new (..); list.Add(ip); update.items = list.ToArray(); 

另外我要指出的一点是,在C#中,您可以在循环内部对for循环中的int变量使用进行delcare:

 for(int i = 0; i 

只是因为我心情很好,这里有一个更简洁的方法来做这个方法IMO:

 private Update BuildMetaData(MetaData[] nvPairs) { Update update = new Update(); var ip = new List(); foreach(var nvPair in nvPairs) { if (nvPair == null) break; var inputProp = new InputProperty { Name = "udf:" + nvPair.Name, Val = nvPair.Value }; ip.Add(inputProp); } update.Items = ip.ToArray(); return update; } 

是否需要是一个数组? 如果您使用ArrayList或C#中可用的其他对象之一,则不会对内容具有此限制。 Hashtable,IDictionnary,IList等都允许动态数量的元素。

用这个:

  Array.Resize(ref myArr, myArr.Length + 5); 

您可以在方法中使用List并将其转换为最后的数组。 但我想如果我们谈论最大值20,你的代码会更快。

  private Update BuildMetaData(MetaData[] nvPairs) { Update update = new Update(); List ip = new List(); for (int i = 0; i < nvPairs.Length; i++) { if (nvPairs[i] == null) break; ip[i] = new InputProperty(); ip[i].Name = "udf:" + nvPairs[i].Name; ip[i].Val = nvPairs[i].Value; } update.Items = ip.ToArray(); return update; } 

或者在使用System.Linq C#3.0中,您可以跳过中间列表:

 private Update BuildMetaData(MetaData[] nvPairs) { Update update = new Update(); var ip = from nv in nvPairs select new InputProperty() { Name = "udf:" + nv.Name, Val = nv.Value }; update.Items = ip.ToArray(); return update; } 

使用Array.CreateInstance动态创建数组。

  private Update BuildMetaData(MetaData[] nvPairs) { Update update = new Update(); InputProperty[] ip = Array.CreateInstance(typeof(InputProperty), nvPairs.Count()) as InputProperty[]; int i; for (i = 0; i < nvPairs.Length; i++) { if (nvPairs[i] == null) break; ip[i] = new InputProperty(); ip[i].Name = "udf:" + nvPairs[i].Name; ip[i].Val = nvPairs[i].Value; } update.Items = ip; return update; } 

通常,数组需要常量来初始化它们的大小。 您可以扫描nvPairs一次以获得长度,然后使用变量长度“动态”创建一个数组,如下所示。

 InputProperty[] ip = (InputProperty[])Array.CreateInstance(typeof(InputProperty), length); 

不过我不推荐它。 坚持下去吧

 List ip = ... ... update.Items = ip.ToArray(); 

解。 它的表现并不是那么低,而且看起来更好看。

您可以通过以下方式动态创建数组:

  static void Main() { // Create a string array 2 elements in length: int arrayLength = 2; Array dynamicArray = Array.CreateInstance(typeof(int), arrayLength); dynamicArray.SetValue(234, 0); // → a[0] = 234; dynamicArray.SetValue(444, 1); // → a[1] = 444; int number = (int)dynamicArray.GetValue(0); // → number = a[0]; int[] cSharpArray = (int[])dynamicArray; int s2 = cSharpArray[0]; }