can smebody explain why .AsSpan thorws an ArrayTypeMismatchException while creating a new ReadOnlySpan doesn't?
SomeMethod(Foo data) {
IPoint[] tmp = (IPoint[])data.Points; // data.Points is OwnPoint[] (class OwnPoint : IPoint)
//ReadOnlySpan<IPoint> pointsSpan = ((IPoint[])tmp).AsSpan(); // System.ArrayTypeMismatchException: 'Attempted to access an element as a type incompatible with the array.'
//ReadOnlySpan<IPoint> pointsSpan = tmp.AsSpan(); // System.ArrayTypeMismatchException: 'Attempted to access an element as a type incompatible with the array.'
ReadOnlySpan<IPoint> pointsSpan = new ReadOnlySpan<IPoint>(tmp);// works
Bar(pointsSpan);
}
public void Bar(ReadOnlySpan<IPoint> pts) {
// ...
}
what am I missing? thought that .AsSpan did the same as creating a new one.
CodePudding user response:
It's a question of type safety. As pointed by @canton7 Span<T>
have check against type, while ReadOnlySpan<T>
doesn't. First one is mutable and it's possible to assign some value to it. As long value have same type, everything is ok, but if value have different type (e.g. ((object[])new string[1])[0] = 1
) array assignment throws ArrayTypeMismatchException
so it won't be possible to have values of different types inside array.
Span<T>
does this check at instantiation time. I don't know motivation behind this, maybe it's performance.
ReadOnlySpan<T>
doesn't need this check since it's not mutable.
You can read more about array casting in chapter 16 "Arrays" in Clr via C# by Jeffrey Richter