C#将主构造函数参数设置为只读


C# 12 引入了一项名为主构造函数 的新功能。此功能允许我们直接在类声明中定义构造函数。

// 您可以直接在类声明中定义构造函数。
public readonly struct Distance(double dx, double dy)
{
    public readonly double Magnitude { get; } = Math.Sqrt(dx * dx + dy * dy);
    public readonly double Direction { get; } = Math.Atan2(dy, dx);
}

此功能对于定义不可变类型很有用。但是,编译器并不强制参数的不变性。

例如,以下代码可以编译:

public class Foo(double value)
{
    // 重写 "value "是可以的,因为在 C# 中允许更新参数
    // 但很多人希望参数是只读的,就像在 records 中一样。
    public void UpdateValue(double newValue) => value = newValue;
}

有多种方法可以解决此问题,并确保参数值不被修改。

解决方案1:使用只读字段
要使参数只读,可以创建一个readonly与参数同名的字段,并将参数的值赋给该字段。然而,这是很多样板代码:

public class Foo(double value)
{
    // 与参数同名的只读字段
    private readonly double value = value;

    // 错误 CS0191:不能将只读字段分配给
    public void UpdateValue(double newValue) => value = newValue;
}

解决方案 2:使用 Roslyn 分析器
另一种解决方案是使用 Roslyn 分析器报告分配参数的所有情况。Meziantou.Analyzer提供了诊断程序来报告此问题。您可以使用以下命令安装该软件包:

dotnet add package Meziantou.Analyzer

安装包后,规则MA0143会报告您项目中的主要构造函数参数的所有赋值,或作为 ref 或 out 参数的使用情况