为何传递ref struct给方法实际是传副本?如何实现按引用传递?
问题描述
定义了如下ref struct:
public ref struct BufferWriter { readonly Buffer* _pb; public int WrittenBytes; //... public bool Append(ReadOnlySpan<byte> buffer) { //... WrittenBytes += buffer.Length; //... } }
将其传递给抽象方法Write100U8Chars(BufferWriter, Object)时,发现是按值传递而非引用传递:
protected override bool Serialize(object obj) { //... fixed (Buffer* pb = &doc_body) { using (BufferWriter writer = new BufferWriter(pb)) { writer.Append("UTF8 str"U8); // pb->Bytes 现在为8 // writer.WrittenBytes 现在也为8 Write100U8Chars(writer, obj); // pb->Bytes 现在为108 // 但 writer.WrittenBytes 仍为8! } } //... } // 该方法始终调用BufferWriter.Append传入100个UTF-8字符(即字节) protected abstract bool Write100U8Chars(BufferWriter writer, object obj);
尝试移除using块、改为ref readonly struct、使用in参数传递均无效,writer.WrittenBytes始终未被方法内的修改同步回来。
请问如何让ref struct像普通非ref struct那样按引用传递给抽象方法?
解决方案
- 给方法参数添加
ref修饰符:这是实现引用传递的直接方式。修改抽象方法的参数定义,调用时也必须带上ref关键字,这样方法内对BufferWriter实例的修改会直接同步到外部。
修改后的抽象方法:
调用代码:protected abstract bool Write100U8Chars(ref BufferWriter writer, object obj);Write100U8Chars(ref writer, obj); - 澄清几个误区:
- 不管是普通struct还是ref struct,默认都是值传递,必须显式用
ref才能实现引用传递,和struct是否带ref修饰无关。 in参数是只读引用,只能读取实例成员,无法修改可变字段(比如WrittenBytes),所以用in无法同步修改结果。ref readonly struct是只读的ref struct,本身限制了对可变成员的修改,自然也解决不了问题。using块的作用是管理对象生命周期(调用Dispose),和参数传递的方式完全无关,移除它不会改变值传递的本质。
- 不管是普通struct还是ref struct,默认都是值传递,必须显式用
内容的提问来源于stack exchange,提问作者D-Kay
相关产品推荐
相关产品推荐

