Visual Studio 建议我将结构体上的方法设置为只读,这是什么意思?我认为只有字段可以是只读的,而不是方法。
public struct MyStruct {
...
// I have this
public void MyMethod() { ... }
// VS wants me to write this
public readonly void MyMethod() { ... }
}
我在 MSDN 上找不到任何标记为只读的 methods 的明确描述,都是关于只读参数或
ref readonly
返回值:
这显然并不意味着返回值变为只读,因为我返回的是 void。在我看来,效果是
this
现在是只读的,但我也想知道这是否意味着它现在与像 in
这样的 ExtMethod(this in MyStruct self)
参数相同,在这种情况下,结构体是通过引用传递的。
具体来说:只读结构方法是否保证
this
通过引用传递,或者它仍然像结构传递给方法时通常那样完全复制(由于是值类型)?
考虑以下情况:
public struct MyStruct
{
public void MyMethod1() { }
public readonly void MyMethod2() { }
}
public static class Test
{
public static void ExtMethod1(this in MyStruct self) => self.MyMethod1();
public static void ExtMethod2(this in MyStruct self) => self.MyMethod2();
public static void ExtMethod3(this MyStruct self) => self.MyMethod2();
public static void ExtMethod4(this ref MyStruct self) => self.MyMethod1();
}
ExtMethod1
中声明self
不应该是change
。但编译器认为该结构是可变的,并且我正在调用它的方法,因此它必须创建一个防御性副本。这可能与预期相反,所以至少我的 IDE 会对此发出警告。ExtMethod2
中仅调用只读方法,因此不需要防御性副本,因为编译器可以确定它没有被修改。ExtMethod3
中,参数未标记为 in
或 ref
,因此将进行复制。ExtMethod4
中明确声明self
可能会变异,因此不会进行复制。请注意,编译器可以自由地进行任何可以进行的优化,只要它可以证明行为不会改变。但证明一个方法可以做什么是非常困难的,因此编译器有时需要开发人员的注释来弄清楚它可以优化什么和不能优化什么。因此,虽然
ExtMethod3
could 中的副本会被删除,但没有任何保证,并且您需要检查汇编器以弄清楚它是否确实已完成。