C# 7.2中返回ref的索引器是否支持set访问器?
关于返回ref的索引器无法添加set访问器的问题解答
你完全没操作错——截至C# 7.2(甚至后续更高版本),返回引用的索引器(以及返回引用的属性)确实不支持set访问器,这是C#语言的设计规则,不是你的代码问题。
咱们来拆解下你给出的几个例子:
可正常运行的只读ref索引器
public ref byte this[int index] { get { return ref bytes[index]; } }
这个写法合法,因为它只提供了引用的读取能力。调用者拿到这个ref之后,就可以直接修改底层数组bytes[index]的值,本质上已经实现了“修改”的效果,根本不需要额外的set访问器。比如调用方可以这么写:
ref byte target = ref yourInstance[5]; target = 0xFF; // 这直接修改了yourInstance内部bytes[5]的值
可正常运行的普通值类型索引器
public byte this[int index] { get { return bytes[index]; } set { bytes[index] = value; } }
这是传统值类型索引器的标准写法:get返回的是bytes[index]的副本,set接收新值再赋值给底层数组,和ref返回的语义完全不同,所以不存在冲突。
为什么带set的ref索引器会报错?
当你尝试给返回ref的索引器添加set访问器时:
public ref byte this[int index] { get { return ref bytes[index]; } set { bytes[index] = value; } }
编译器抛出CS8147错误,核心原因是:ref返回的成员设计初衷就是让调用者直接操作底层存储的引用,而set访问器的语义是“接收一个新值并间接赋值”,这两者的逻辑是重叠且冲突的——既然调用者已经能拿到底层的引用直接修改,再提供set访问器就完全多余了,C#语言干脆从语法上禁止了这种写法。
总结一下:如果你的需求是让调用者既能读取又能修改底层的bytes元素,只需要保留返回ref的get访问器就足够了,不需要额外加set。
内容的提问来源于stack exchange,提问作者Fit Dev
相关产品推荐
相关产品推荐

