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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/683073/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 13:17:03  来源:igfitidea点击:

How to set array length in c# dynamically

c#arraysobjectarray-initialize

提问by John Adams

I am still new to C# and I've been struggling with various issues on arrays. I've got an array of metadata objects (name value pairs) and I would like to know how to create only the number of "InputProperty" objects that I truly need. In this loop I've arbitrarily set the number of elements to 20 and I try to bail out when the entry becomes null but the web service on the receiving end of this does not like any null elements passed to it:

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

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

In summary, say I only have 3 namevalue pairs in the above input array? Rather than allocate 20 elements for the array called ip, how can code this so ip is only as big as it needs to be. The update object is passed across another webservice so serialization is important (i.e. I can't use namevaluecollection, etc.).

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

p.s. Is the only way to followup on a posted question through the "add comments" facility?

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

采纳答案by Jim Mischel

If you don't want to use a List, ArrayList, or other dynamically-sized collection and then convert to an array (that's the method I'd recommend, by the way), then you'll have to allocate the array to its maximum possible size, keep track of how many items you put in it, and then create a new array with just those items in it:

如果你不想使用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;
}

An alternate method would be to always assign update.Items = ip;and then resize if necessary:

另一种方法是始终分配update.Items = ip;,然后在必要时调整大小:

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

It's less code, but will likely end up doing the same amount of work (i.e. creating a new array and copying the old items).

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

回答by BFree

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

Or, you can use a list like so:

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

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

Another thing I'd like to point out, in C# you can delcare your int variable use in a for loop right inside the loop:

我想指出的另一件事是,在 C# 中,您可以在循环内部的 for 循环中使用 int 变量:

for(int i = 0; i<nvPairs.Length;i++
{
.
.
}

And just because I'm in the mood, here's a cleaner way to do this method IMO:

只是因为我心情好,这里有一种更简洁的方法来执行此方法 IMO:

private Update BuildMetaData(MetaData[] nvPairs)
{
        Update update = new Update();
        var ip = new List<InputProperty>();

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

回答by Brian

Does is need to be an array? If you use an ArrayList or one of the other objects available in C#, you won't have this limitation to content with. Hashtable, IDictionnary, IList, etc.. all allow a dynamic number of elements.

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

回答by Michael Piendl

You could use List inside the method and transform it to an array at the end. But i think if we talk about an max-value of 20, your code is faster.

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

    private Update BuildMetaData(MetaData[] nvPairs)
    {
        Update update = new Update();
        List<InputProperty> ip = new List<InputProperty>();
        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;
    }

回答by dahlbyk

Or in C# 3.0 using System.Linqyou can skip the intermediate list:

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

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

回答by Michael Meadows

Typically, arrays require constants to initialize their size. You could sweep over nvPairs once to get the length, then "dynamically" create an array using a variable for length like this.

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

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

I wouldn't recommend it, though. Just stick with the

不过,我不会推荐它。只要坚持

List<InputProperty> ip = ...
...
update.Items = ip.ToArray();

solution. It's not that much less performant, and way better looking.

解决方案。它的性能并没有那么差,而且看起来更好看。

回答by kilan

Use this:

用这个:

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

回答by Johannes

Use Array.CreateInstanceto create an array dynamically.

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

回答by lukaszk

You can create an array dynamically in this way:

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

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

    }