.AsSpan 数组类型不匹配异常

.AsSpan ArrayTypeMismatchException

谁能解释为什么 .AsSpan 抛出 ArrayTypeMismatchException 而创建新的 ReadOnlySpan 却没有?

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) {
    // ...
}

我错过了什么?认为 .AsSpan 与创建新的一样。

这是类型安全的问题。正如@canton7 所指出的,Span<T> 已经检查了类型,而 ReadOnlySpan<T> 没有。第一个是可变的,可以为其分配一些值。由于 long 值具有相同的类型,一切都可以,但是如果值具有不同的类型(例如 ((object[])new string[1])[0] = 1),则数组赋值会抛出 ArrayTypeMismatchException,因此数组中不可能有不同类型的值。

Span<T> 在实例化时执行此检查。我不知道这背后的动机,也许是性能。

ReadOnlySpan<T> 不需要这个检查,因为它是不可变的。

您可以在 Jeffrey Richter 的 Clr via C# 中的第 16 章“数组”中阅读有关数组转换的更多信息