难以通过反射重新调整数组大小

时间:2015-10-25 03:39:04

标签: c# arrays reflection resize

我试图用反射重新调整任意类型数组的大小。这是我的代码:

public static void TestResizeArray()
{
    int[]
        ints;
    Array
        arrayOfInts;

    ints = new int[ 3 ];
    arrayOfInts = (Array) ints;
    ResizeArray( ref arrayOfInts, 5 );
    Debug.Assert( arrayOfInts.Length == 5 ); // passes
    Debug.Assert( ints.Length == 5 ); // FAILS <<<<<<<<<<<
}

public static void ResizeArray(
    ref Array
        theArray,
    int
        newSize )
{
    MethodInfo
        methodInfo,
        genericMethodInfo;
    object[]
        parameters;

    methodInfo = typeof( Array ).GetMethod(
        "Resize",
        BindingFlags.Public | BindingFlags.Static );
    genericMethodInfo = methodInfo.MakeGenericMethod(
        theArray.GetType().GetElementType() );
    parameters = new object[] { theArray, newSize };
    genericMethodInfo.Invoke( null, parameters );
    theArray = (Array) parameters[ 0 ];
}

调用泛型Array.Resize(...)函数正在运行,因为参数[0]包含重新调整大小的数组,但它没有更改theArray变量。将theArray设置为参数[0]部分有效,因为调用函数中的arrayOfInts会重新调整大小,但这似乎会将int数组与arrayOfInts断开连接。

如何更改此设置以便调整ints数组的大小?

提前致谢。

2 个答案:

答案 0 :(得分:1)

intsarrayOfInts是两个不同的引用变量,它们首先指向同一个数组实例。调整器返回一个新的数组实例并将其分配给arrayOfInts。这两个引用现在指向不同的对象,它们之间没有链接。如果您希望ints指向新对象,则必须将新值指定给它,或者将其直接传递给缩放器。

答案 1 :(得分:1)

让我们看一下Array.Resize方法:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[__DynamicallyInvokable]
public static void Resize<T>(ref T[] array, int newSize)
{
  if (newSize < 0)
    throw new ArgumentOutOfRangeException("newSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  T[] objArray1 = array;
  if (objArray1 == null)
  {
    array = new T[newSize];
  }
  else
  {
    if (objArray1.Length == newSize)
      return;
    T[] objArray2 = new T[newSize];
    Array.Copy((Array) objArray1, 0, (Array) objArray2, 0, objArray1.Length > newSize ? newSize : objArray1.Length);
    array = objArray2;
  }
}

如您所见,有一个Array.Copy调用。因此,此方法创建新数组并将指向此数组的指针设置为array参数。 您的intsarrayOfInts是指向一个数组的不同指针,当您将arrayOfInts传递给方法时,它只会修改此变量。