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

C# ref struct委托赋值报错:为何常规结构体/类可正常运行?

问题原因解析

首先你的代码里存在一个参数类型不匹配的基础错误:
你定义的委托MyDelegate要求参数是ReadOnlySpan<string>,但Method1和Method2的参数是ReadOnlySpan<T>,两者类型完全不兼容,这本身就会触发"No overload matches delegate"的错误——这个问题在常规结构体/类里也会出现,只是你可能之前测试的代码参数是匹配的。

假设修正参数类型后(比如把委托的参数改成ReadOnlySpan<T>),ref struct里依然无法通过条件运算符给委托赋值,这是因为ref struct的核心限制:

  • ref struct是栈绑定类型,绝对不允许被分配到托管堆上,也不能被任何可能涉及堆分配的结构捕获(比如闭包、委托的目标对象)。
  • 当你把结构体的实例方法赋值给委托时,编译器会生成一个包含该结构体实例的委托对象。对于常规值类型结构体,这个实例会被复制到堆上的委托对象中;但ref struct禁止被复制到堆,因此无法生成合法的委托。
  • 常规类的方法赋值给委托时,捕获的是类实例的引用(堆上的地址),不存在堆分配新对象的问题;常规结构体如果用static方法赋值也不会有问题,但实例方法就会涉及值复制到堆,而ref struct完全禁止这种操作。

解决办法

如果要在ref struct中使用委托,只能绑定静态方法,或者通过其他方式避免捕获ref struct的实例:

public ref struct MyRefStruct<T>
{
    delegate T MyDelegate(ReadOnlySpan<T> span);
    
    MyDelegate _creator;

    public MyRefStruct(bool myCondition)
    {
         // 使用静态方法,无需捕获this
         _creator = myCondition ? StaticMethod1 : StaticMethod2;
    }

    static T StaticMethod1(ReadOnlySpan<T> span) { /* ... */ }
    static T StaticMethod2(ReadOnlySpan<T> span) { /* ... */ }
}

内容的提问来源于stack exchange,提问作者cws-apellegrino

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 23:51:03