如何在C#中转换(ReadOnly)Span<Dog>与(ReadOnly)Span<Animal>?
关于Span/ReadOnlySpan在引用类型间转换的问题
以下是我尝试的几种Span转换场景,所有转换均报错,本质属于同一问题:
- 能否将
Span<Dog>转换为Span<Animal>? - 能否将
Span<Animal>转换为Span<Dog>? - 能否将
ReadOnlySpan<Dog>转换为ReadOnlySpan<Animal>? - 能否将
ReadOnlySpan<Animal>转换为ReadOnlySpan<Dog>?
问题示例代码
class Animal { } class Dog : Animal { } void Main() { Dog[] dogs = new Dog[10]; Span<Dog> dogSpan = dogs.AsSpan(0, 10); // CS0030 无法将类型“System.Span<Dog>”转换为“System.Span<Animal>” Span<Animal> animalSpan1 = (Span<Animal>)dogSpan; // CS0453 类型“Dog”必须为非空值类型,才能用作泛型类型或方法“MemoryMarshal.Cast<TFrom, TTo>(ReadOnlySpan<TFrom>)”的参数“TFrom” // CS0453 类型“Animal”必须为非空值类型,才能用作泛型类型或方法“MemoryMarshal.Cast<TFrom, TTo>(ReadOnlySpan<TFrom>)”的参数“TTo” Span<Animal> animalSpan2 = MemoryMarshal.Cast<Dog, Animal>(dogSpan); }
需求说明
我可以接受不安全转换,哪怕传入Giraffe导致运行时崩溃也无所谓。搜索到的Span<byte>转Span<int>这类是重新解释内存的转换,不是我需要的。如果确实无法实现,请告知相关官方文档说明。
我的使用场景是用ReadOnlySpan表示只读托管数组(比如Animal[])的范围,消费者需要处理特定的Animal实现(比如GiraffeHandler接收ReadOnlySpan<Animal>并将其视为ReadOnlySpan<Giraffe>)。
我知道两种替代方案:分配数组副本生成新的Span,或者每次取元素时转换(用ref struct包装),但这些方案都不够优雅。希望能直接实现两种Span的转换,或者明确知道无法实现的原因。
内容的提问来源于stack exchange,提问作者Warty
相关产品推荐
相关产品推荐

