不同 getter 样式之间的 C# 差异

Difference in C# between different getter styles

我有时会在 getter 的属性中看到缩写。例如。这两种类型:

public int Number { get; } = 0

public int Number => 0;

谁能告诉我这两者之间是否有任何区别。他们的行为如何?它们都是只读的吗?

是的,两者都是只读的,但还是有区别的。在第一个中,有一个在执行构造函数之前初始化为 0 的支持字段。您只能在构造函数 中更改值 ,就像常规的只读字段一样。 getter 本身只是 returns 字段的值。

在第二个中,getter 每次都是 returns 0,不涉及任何字段。

因此,为了完全避免使用任何自动实现的属性或表达式体成员,我们有:

第一个版本

private readonly int _number = 0;
public int Number { get { return _number; } }

第二个版本

public int Number { get { return 0; } }

一个更清晰的差异示例如下所示:

public DateTime CreationTime { get; } = DateTime.UtcNow;
public DateTime CurrentTime => DateTime.UtcNow;

如果您创建单个对象,其 CreationTime 属性 将始终给出相同的结果 - 因为它存储在只读字段中,在对象构造时初始化。但是,每次访问 CurrentTime 属性 时,都会导致对 DateTime.UtcNow 求值,因此您可能会得到不同的结果。

这些是 C# 6 语言特性。

第一个例子

public int Number { get; } = 0

第一个例子是getter-only auto property。 getter-only auto-属性 的支持字段被隐式声明为只读。

第二个例子

public int Number => 0;

第二个例子是expression bodies on property-like function members。请注意,没有任何 get 关键字:它是通过使用表达式主体语法来暗示的。

两者都是只读的。

一个区别是何时评估 0:在对象创建时或使用 属性 时。

您可以使用 DateTime 属性更好地了解这一点:

class SomeTestClass
{
    public DateTime Start { get; } = DateTime.Now;

    public DateTime Now => DateTime.Now;
}

Start 属性 保持返回相同的时间(创建实例的时间),而 Now 更改以反映当前时间。

解释:

第一个版本 ("Start") 提供了一个初始值,甚至可以被构造函数覆盖。所以这只被评估一次。
第二个版本 ("Now") 提供的表达式将成为此 属性 的 "getter"。因此,每次读取 属性 时都会对其进行评估。甚至没有构造函数可以覆盖的支持字段。