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
相关产品推荐
相关产品推荐

