Add optional polyfill (alias) to support getsubarray
arcutright opened this issue · 1 comments
Rationale
Slicing arrays is a fairly common task, and a workaround is simple.
Proposed API
Optional property flag in .csproj to alias System.Runtime.CompilerServices.RuntimeHelpers
<PolySharpAliasRuntimeHelpers>true</PolySharpAliasRuntimeHelpers>
Drawbacks
Obvious, see previous discussion in #8
Alternatives
Not sure there's any other way to support modern C# range syntax for arrays and spans.
Proposed hack
- Generate a copy of .net framework's class: https://referencesource.microsoft.com/#mscorlib/system/runtime/compilerservices/runtimehelpers.cs,b8d6172d5976a77a or steal from net core: https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs,7fb1a6c958ce626e,references
- Add an implementation for GetSubArray
minimal example, excluding everything else from RuntimeHelpers
public static partial class RuntimeHelpers {
// runtime support for range operator eg `myarray[0..5]`
public static T[] GetSubArray<T>(T[] array, System.Range range) {
var (offset, length) = range.GetOffsetAndLength(array.Length);
if (length == 0)
return Array.Empty<T>();
T[] dest;
if (typeof(T).IsValueType || typeof(T[]) == array.GetType()) {
// 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<T>();
dest = new T[length];
}
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 = (T[])(Array.CreateInstance(array.GetType().GetElementType(), length));
}
Array.Copy(array, offset, dest, 0, length);
return dest;
}
}
"Not sure there's any other way to support modern C# range syntax for arrays and spans."
The issue is just for arrays, not spans. Slicing spans with the built-in syntax already works perfectly fine, as it doesn't require the runtime helper method. And slicing arrays is something that one shouldn't really do much at all if possible anyway. I don't think it's worth the extra complexity, also so far I've tried to avoid polyfilling methods to avoid things getting too out of hand 🙂