在C#中使用Redim Preserve?

时间:2008-11-29 19:44:15

标签: c# arrays

我很惊讶今天发现C#不支持动态大小的数组。然后,VB.NET开发人员如何使用ReDim Preserve在C#中处理此问题?

在函数的开头我不确定数组的上限。这取决于从数据库返回的行。

7 个答案:

答案 0 :(得分:74)

VB.NET也没有动态大小的数组的想法--CLR不支持它。

相当于“Redim Preserve”是Array.Resize<T> - 但是必须知道如果对原始数组有其他引用,它们将根本不会被更改。例如:

using System;

class Foo
{
    static void Main()
    {
        string[] x = new string[10];
        string[] y = x;

        Array.Resize(ref x, 20);
        Console.WriteLine(x.Length); // Prints out 20
        Console.WriteLine(y.Length); // Still prints out 10
    }
}

证明这相当于Redim Preserve:

Imports System

Class Foo
    Shared Sub Main()
        Dim x(9) as String
        Dim y as String() = x

        Redim Preserve x(19)
        Console.WriteLine(x.Length)
        Console.WriteLine(y.Length)
    End Sub
End Class

这两个计划是等效的。

如果你真的想要一个动态大小的集合,你应该使用List<T>(或类似的东西)。直接使用数组存在各种问题 - 有关详细信息,请参阅Eric Lippert's blog post。这并不是说你应该总是以任何方式避免它们 - 但你需要知道你在处理什么。

答案 1 :(得分:11)

使用ArrayLists或Generics

答案 2 :(得分:10)

使用列表&lt; T&gt;。它将根据需要动态调整大小。

答案 3 :(得分:4)

你真的不应该使用ReDim,它可能是每一个昂贵的。我更喜欢List(Of T),但这方面有很多选择。

那就是说,你有一个问题,这是你的答案。

x = (int[]) Utils.CopyArray((Array) x, new int[10]);

答案 4 :(得分:2)

我忍不住注意到上述答案的 none 接近多维数组的概念。话虽这么说,这是一个例子。有问题的数组预定义为x

int[,] temp = new int[newRows, newCols];
int minRows = Math.Min(newRows, x.GetUpperBound(0) + 1);
int minCols = Math.Min(newCols, x.GetUpperBound(1) + 1);
for (int i = 0; i < minRows ; ++i)
     for (int j = 0; j < minCols; ++j)
         temp[i, j] = x[i, j];
x = temp;

答案 5 :(得分:2)

只是为了好玩,这里有一种使用泛型来重新/扩展一维数组的方法(再加一个“行”):

static T[] Redim<T>(T[] arr, bool preserved)
{
    int arrLength = arr.Length;
    T[] arrRedimed = new T[arrLength + 1];
    if (preserved)
    {
        for (int i = 0; i < arrLength; i++)
        {
            arrRedimed[i] = arr[i];
        }
    }
    return arrRedimed;
}

一个添加n行(虽然这不会阻止用户缩小数组,这会在for循环中引发错误):

static T[] Redim<T>(T[] arr, bool preserved, int nbRows)
{
    T[] arrRedimed = new T[nbRows];
    if (preserved)
    {
        for (int i = 0; i < arr.Length; i++)
        {
            arrRedimed[i] = arr[i];
        }
    }
    return arrRedimed;
}

我相信你明白了。

对于多维数组(二维),这里有一种可能性:

static T[,] Redim<T>(T[,] arr, bool preserved)
{
    int Ubound0 = arr.GetUpperBound(0);
    int Ubound1 = arr.GetUpperBound(1);
    T[,] arrRedimed = new T[Ubound0 + 1, Ubound1];
    if (preserved)
    {
        for (int j = 0; j < Ubound1; j++)
        {
            for (int i = 0; i < Ubound0; i++)
            {
                arrRedimed[i, j] = arr[i, j];
            }
        }
    }
    return arrRedimed;
}

在你的程序中,使用它甚至没有指定的类型,编译器将识别它:

int[] myArr = new int[10];
myArr = Redim<int>(myArr, true);

int[] myArr = new int[10];
myArr = Redim(myArr, true);

不确定这一切是否真的相关。 = d 请随时纠正我或改进我的代码。 ;)

答案 6 :(得分:1)

Even though it's a long time ago it might help someone looking for a simple solution - I found something great in another forum:

//from Applied Microsoft.NET framework Programming - Jeffrey Richter
public static Array RedimPreserve(Array origArray, Int32 desiredSize)
        {
            System.Type t = origArray.GetType().GetElementType();
            Array newArray = Array.CreateInstance(t, desiredSize);
            Array.Copy(origArray, 0, newArray, 0, Math.Min(origArray.Length, desiredSize));
            return newArray;
        }

Source: https://social.msdn.microsoft.com/Forums/en-US/6759816b-d525-4752-a3c8-9eb5f4a5b194/redim-in-c?forum=csharplanguage