我正在尝试熟悉 C# 12 主构造函数变量。
这是我的代码:
public class BankAccountNew(string accountID, string owner)
{
public void DoSomethingWrong()
{
accountID = "Wrong";
}
}
public class BankAccounOld
{
private readonly string accountID;
private readonly string owner;
public BankAccounOld(string accountID, string owner)
{
this.accountID = accountID;
this.owner = owner;
}
public void DoSomethingWrong()
{
accountID = "Wrong";
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我希望DoSomethingWrong在修改我想要只读的参数时触发编译器错误。我在这方面取得了成功,BankAccounOld但这需要我输入大量代码,而在最新的 C# 版本中不再需要这些代码。
正如所解释的accountID,应该是只读的。如何进行更改BankAccountNew以确保将其识别为只读,从而触发编译器错误?
Panagiotis Kanavos 在评论中已经提到过,有一个中间解决方案可以正确触发编译器错误。在以下示例中,不会accountID生成任何字段,但其值会myAccountID在实例化时分配给该字段。
public class BankAccoun(string accountID, string owner)
{
private readonly string myAccountID = accountID;
private readonly string myOwner = owner;
public void DoSomethingWrong()
{
myAccountID = "Wrong";
}
}
Run Code Online (Sandbox Code Playgroud)
这里需要注意的是,该字段accountID是生成的并且可以更改,以防在类中访问它。例如,如果您将方法更改为:
public void DoSomethingWrong()
{
accountID = "Wrong";
}
Run Code Online (Sandbox Code Playgroud)
您可以通过将只读字段命名为与构造函数参数相同的名称来防止这种情况发生。根据Sharplab.io,以下工作按您的要求进行:
public class BankAccoun(string accountID, string owner)
{
private readonly string accountID = accountID;
private readonly string owner = owner;
public void DoSomethingWrong()
{
accountID = "Wrong";
}
}
Run Code Online (Sandbox Code Playgroud)
似乎有一种方法可以将参数声明为主构造函数中的“in”。以下代码片段有效:
public class SomeClass(in int param)
{
private readonly int _param = param;
public int GetSum(int other)
{
// Cannot access 'param' here.
return other + _param;
}
}
Run Code Online (Sandbox Code Playgroud)
主构造函数参数现在在该方法中不可用,但仅在私有只读字段的初始化中可用,使其有效地只读。
编辑:在赋值中写入 '++param' 会导致编译器错误,因此 if 实际上是只读的。
主构造函数是新的,仍然存在一些限制。
readonly目前还不可能制造它们,但希望很快就能实现。
Nick Chapsas 的这段视频对此进行了很好的解释,他还研究了 IL 代码。
https://youtu.be/hcCT5J-SKEA?si=Ka-W7Cxp-dVABTRn&t=240