You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 09:50:31