难以通过反射调整数组大小
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 数组的大小?
提前致谢。
ints
和 arrayOfInts
是两个不同的引用变量,它们首先指向同一个数组实例。调整器 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
参数。
您的 ints
和 arrayOfInts
是指向一个数组的不同指针,当您将 arrayOfInts
传递给方法时,它只会重写这个变量。
我正在尝试通过反射调整任意类型数组的大小。这是我的代码:
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 数组的大小?
提前致谢。
ints
和 arrayOfInts
是两个不同的引用变量,它们首先指向同一个数组实例。调整器 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
参数。
您的 ints
和 arrayOfInts
是指向一个数组的不同指针,当您将 arrayOfInts
传递给方法时,它只会重写这个变量。