@@ -54,17 +54,33 @@ public static void Resize<T>([NotNull] ref T[]? array, int newSize)
5454
5555 if ( larray . Length != newSize )
5656 {
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.
6278
63- T [ ] newArray = new T [ newSize ] ;
6479 Buffer . Memmove (
6580 ref MemoryMarshal . GetArrayDataReference ( newArray ) ,
6681 ref MemoryMarshal . GetArrayDataReference ( larray ) ,
6782 ( uint ) Math . Min ( newSize , larray . Length ) ) ;
83+
6884 array = newArray ;
6985 }
7086
0 commit comments