Unity中如何将函数参数设置为ReadOnly?
Unity函数参数的[ReadOnly]特性使用解析
核心结论
可以给函数传入的变量标记[ReadOnly],而且在Unity Native容器+Burst编译的场景下非常有必要,绝非多此一举。
你对默认参数传递的误区澄清
你提到“不使用ref关键字时参数默认是只读的”,这个理解不完全准确:
- 对于普通值类型(比如
int、自定义结构体),默认传值是复制一份副本,函数里修改副本不会影响原变量,但这只是“不影响外部”,并非强制函数内部不能修改副本; - 对于引用类型(比如普通C#类),默认传的是引用的副本,函数里依然可以修改对象的内部状态;
- 而Unity的
NativeList这类Native容器是值类型结构体,但内部持有关联的堆内存,默认传值时会复制结构体,但内部的内存引用还是指向同一块堆内存,这时候函数里如果修改NativeList的内容,会直接影响原变量的堆内存数据。
你的代码示例中[ReadOnly]的作用
看你给出的代码:
private void func1() { var newList = new NativeList<int>(1024, Allocator.Temp); // 写入newList数据 func2(newList); } // 需要支持Burst编译 [BurstCompile] private static void func2([ReadOnly] NativeList<int> newList) { // 仅对newList执行读取操作 }
这里的[ReadOnly]有三个关键作用:
- Burst编译优化:告诉Burst编译器这个
NativeList只会被读取,不会被修改,Burst可以跳过不必要的线程安全检查(比如写入锁),生成更高效的机器码; - 代码契约与防误操作:明确标记这个函数只会读取参数,禁止在函数内部编写修改
NativeList的逻辑,编译器会直接报错,避免后续维护时的误修改; - Unity线程安全保障:Native容器的安全系统会根据
[ReadOnly]标记,允许该参数在多线程环境下被安全访问,不会触发读写冲突的异常。
额外补充
如果是普通的自定义结构体参数,标记[ReadOnly]同样会让编译器禁止在函数内部修改该结构体的成员变量,起到强制只读的作用;而普通C#引用类型参数,Unity的[ReadOnly]特性不会限制对对象内部状态的修改,这时候如果需要只读约束,通常会用只读接口或者自定义只读包装类。
内容的提问来源于stack exchange,提问作者Swtsvn
相关产品推荐
相关产品推荐

