diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs index 4215db4af11cec..af72ceb7af9933 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -27,33 +27,18 @@ public static T[] GetSubArray(T[] array, Range range) (int offset, int length) = range.GetOffsetAndLength(array.Length); - T[] dest; - - if (typeof(T).IsValueType || typeof(T[]) == array.GetType()) + if (length == 0) { - // We know the type of the array to be exactly T[] or an array variance - // compatible value type substitution like int[] <-> uint[]. - - if (length == 0) - { - return Array.Empty(); - } - - dest = new T[length]; + return Array.Empty(); } - else - { - // The array is actually a U[] where U:T. We'll make sure to create - // an array of the exact same backing type. The cast to T[] will - // never fail. - dest = Unsafe.As(Array.CreateInstance(array.GetType().GetElementType()!, length)); - } + T[] dest = new T[length]; - // In either case, the newly-allocated array is the exact same type as the - // original incoming array. It's safe for us to Buffer.Memmove the contents - // from the source array to the destination array, otherwise the contents - // wouldn't have been valid for the source array in the first place. + // Due to array variance, it's possible that the incoming array is + // actually of type U[], where U:T; or that an int[] <-> uint[] or + // similar cast has occurred. In any case, since it's always legal + // to reinterpret U as T in this scenario (but not necessarily the + // other way around), we can use Buffer.Memmove here. Buffer.Memmove( ref MemoryMarshal.GetArrayDataReference(dest),