@@ -54,17 +54,33 @@ public static void Resize<T>([NotNull] ref T[]? array, int newSize)
54
54
55
55
if ( larray . Length != newSize )
56
56
{
57
- // Due to array variance, it's possible that the incoming array is
58
- // actually of type U[], where U:T; or that an int[] <-> uint[] or
59
- // similar cast has occurred. In any case, since it's always legal
60
- // to reinterpret U as T in this scenario (but not necessarily the
61
- // other way around), we can use SpanHelpers.Memmove here.
57
+ T [ ] newArray ;
58
+
59
+ if ( larray . GetType ( ) == typeof ( T [ ] ) )
60
+ {
61
+ // We know the type of the array to be exactly T[].
62
+
63
+ newArray = new T [ newSize ] ;
64
+ }
65
+ else
66
+ {
67
+ // The array is actually a U[] where U:T. We'll make sure to create
68
+ // an array of the exact same backing type. The cast to T[] will
69
+ // never fail.
70
+
71
+ newArray = Unsafe . As < T [ ] > ( Array . CreateInstanceFromArrayType ( larray . GetType ( ) , newSize ) ) ;
72
+ }
73
+
74
+ // In either case, the newly-allocated array is the exact same type as the
75
+ // original incoming array. It's safe for us to Buffer.Memmove the contents
76
+ // from the source array to the destination array, otherwise the contents
77
+ // wouldn't have been valid for the source array in the first place.
62
78
63
- T [ ] newArray = new T [ newSize ] ;
64
79
Buffer . Memmove (
65
80
ref MemoryMarshal . GetArrayDataReference ( newArray ) ,
66
81
ref MemoryMarshal . GetArrayDataReference ( larray ) ,
67
82
( uint ) Math . Min ( newSize , larray . Length ) ) ;
83
+
68
84
array = newArray ;
69
85
}
70
86
0 commit comments