用这种方式自己创建字段/属性是没有意义的,因为在这种情况下,编译器会为您创建它们(反编译@sharplab.io).
从Tutorial: Explore primary constructors个文档(它们使用struct
,但主ctor的处理是相同的):
public struct Distance(double dx, double dy)
{
public readonly double Magnitude => Math.Sqrt(dx * dx + dy * dy);
public readonly double Direction => Math.Atan2(dy, dx);
public void Translate(double deltaX, double deltaY)
{
dx += deltaX;
dy += deltaY;
}
public Distance() : this(0,0) { }
}
在上一个示例中,在方法中访问主要构造函数属性.因此,编译器创建隐藏字段来表示每个参数.下面的代码大致显示了编译器生成的内容.实际的字段名是有效的CIL标识符,但不是有效的C#标识符.
public struct Distance
{
private double __unspeakable_dx;
private double __unspeakable_dy;
public readonly double Magnitude => Math.Sqrt(__unspeakable_dx * __unspeakable_dx + __unspeakable_dy * __unspeakable_dy);
public readonly double Direction => Math.Atan2(__unspeakable_dy, __unspeakable_dx);
public void Translate(double deltaX, double deltaY)
{
__unspeakable_dx += deltaX;
__unspeakable_dy += deltaY;
}
public Distance(double dx, double dy)
{
__unspeakable_dx = dx;
__unspeakable_dy = dy;
}
public Distance() : this(0, 0) { }
}
潜在的缺点是生成的字段是可变的:
public class Calculation(int a, int b)
{
public void Mutate() => a = 100;
// ...
}
虽然您的方法不能解决这个问题,但是当您可以混淆_a
和a
时,它会带来一些混乱.目前无法将生成的字段标记为readonly
(但有针对该功能的计划-请参见this LDM notes doc和this proposal),但您可以使用具有相同名称(或属性)的字段来隐藏ctor参数:
public class Calculation2(int a, int b)
{
private readonly int a = a;
private readonly int b = b;
// public void Mutate() => a = 100; // does not compile
public int Addition() => a + b;
public int Subtraction() => a - b;
}
另见: