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

发布于 2024-07-15 23:33:48 字数 808 浏览 7 评论 0原文

我对 C# 还是个新手,一直在努力解决数组上的各种问题。 我有一个元数据对象数组(名称值对),我想知道如何仅创建我真正需要的“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 是通过“添加评论”功能跟进已发布问题的唯一方法吗?

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:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

裂开嘴轻声笑有多痛 2024-07-22 23:33:48
InputProperty[] ip = new InputProperty[nvPairs.Length]; 

或者,您可以使用这样的列表:

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

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

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

只是因为我有心情,这里有一个在我看来,执行此方法的更简洁方法:

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

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:

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;
}
苍风燃霜 2024-07-22 23:33:48

如果您不想使用 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; 然后在必要时调整大小:

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

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

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:

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

困倦 2024-07-22 23:33:48

用这个:

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

Use this:

 Array.Resize(ref myArr, myArr.Length + 5);
﹏雨一样淡蓝的深情 2024-07-22 23:33:48

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

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.

请恋爱 2024-07-22 23:33:48

您可以在方法内使用 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;
    }

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.

    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;
    }
-小熊_ 2024-07-22 23:33:48

或者在 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;
}

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

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;
}
我要还你自由 2024-07-22 23:33:48

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

Use Array.CreateInstance to create an array dynamically.

    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;
    }
荭秂 2024-07-22 23:33:48

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

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

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

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

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

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.

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.

究竟谁懂我的在乎 2024-07-22 23:33:48

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

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

    }

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

    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文