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

Difficulty re-sizing array with reflection

我正在尝试通过反射调整任意类型数组的大小。这是我的代码:

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(...) 函数有效,因为 parameters[0] 包含重新调整大小的数组,但它没有更改 theArray 变量。将 theArray 设置为 parameters[0] 部分有效,因为调用函数中的 arrayOfInts 被重新调整大小,但这似乎断开了 ints 数组与 arrayOfInts.

我如何更改它以便调整 ints 数组的大小?

提前致谢。

intsarrayOfInts 是两个不同的引用变量,它们首先指向同一个数组实例。调整器 returns 一个新的数组实例并将其分配给 arrayOfInts。这两个引用现在指向不同的对象,并且它们之间没有 link。如果你想让 ints 指向新对象,你必须将新值赋回给它,或者直接将它传递给 resizer。

让我们看看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 传递给方法时,它只会重写这个变量。