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

C# CS1612错误解惑:返回值不可作为变量修改的原因

CS1612错误原因分析与解决方案

错误根源

第一个场景的问题

GetStatsByType返回的RefValue<Stats>是栈上的临时值类型实例,虽然Item1是ref readonly T字段,但临时实例的生命周期仅局限于当前表达式执行阶段。当你尝试通过这个临时实例访问Item1并返回其引用时,编译器会阻止这种操作——表达式结束后临时实例会被销毁,对应的引用会变成无效的悬垂引用,因此触发CS1612错误。

第二个尝试的问题

你在return语句中直接创建RefTuple<Stats>临时实例并返回其Item1引用,本质和第一个问题一致:临时ref struct实例的生命周期太短,返回它的成员引用会导致悬垂引用,C#编译器禁止这种不安全的操作。

解决方案

方案一:直接返回字典值的引用(推荐)

去掉中间的RefValue<T>包装,让GetStatsByType直接返回CollectionsMarshal.GetValueRefOrAddDefault给出的引用。这个引用直接指向字典内部的Stats实例,生命周期由字典管理,安全且有效:

public ref readonly Stats GetStatsByType(TileType t)
{
    return ref CollectionsMarshal.GetValueRefOrAddDefault(_typeStats, t, out _);
}

// 现在该属性可正常编译
public ref readonly Stats ExampleAsRef => ref GetStatsByType(TileType.Blue);

方案二:保留RefValue<T>的前提(仅适用于ref struct容器)

如果必须保留RefValue<T>结构体(比如封装多个ref字段),需要确保RefValue<T>实例不是临时值:

  • 若你的类型本身是ref struct,可以将RefValue<T>作为字段存储,再返回该字段的Item1引用;
  • 若你使用的是普通类,由于普通类不能包含ref struct类型的字段,这种场景下无法用RefValue<T>中转引用,只能选择方案一。

内容的提问来源于stack exchange,提问作者Shpendicus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:01:10