C#中in修饰符调用差异:加与不加的区别及结构体拷贝问题
C#中
in修饰符调用时指定与不指定的区别及结构体拷贝问题 先明确基础用法
ref修饰符的用法
struct Point { float x, y; } float Dst(ref Point a, ref Point b) { // 方法内可读取并修改a、b的成员 return 0f; }
调用时必须显式加ref:
Point a, b; // 初始化a、b float dst = Dst(ref a, ref b);
in修饰符的用法
in修饰符等价于只读引用,方法内无法修改参数的成员,且调用时可选是否加in:
float Dst(in Point a, in Point b) { // 仅能读取a、b的成员,无法修改 return 0f; }
调用方式两种都合法:
Point a, b; // 初始化a、b float dst1 = Dst(in a, in b); float dst2 = Dst(a, b);
核心区别与拷贝情况
1. 显式指定in时
直接以只读引用的方式传递原结构体实例,完全不会产生结构体拷贝。方法内部只能访问结构体的成员,不能做任何修改操作(编译器会阻止修改行为)。
2. 不指定in时
编译器会根据结构体的类型自动处理:
- 如果是** blittable 结构体**(比如示例中的
Point,仅包含值类型成员,符合 blittable 规则):编译器会隐式按只读引用传递,和显式加in效果一致,无拷贝。 - 如果是非blittable结构体(比如包含字符串、自定义引用类型成员,或不符合 blittable 规则的结构体):编译器会先创建一个原结构体的临时拷贝,再将这个拷贝的只读引用传递给方法,此时会发生一次结构体拷贝。
内容的提问来源于stack exchange,提问作者Dmitriy Sitnikov
相关产品推荐
相关产品推荐

