不同 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"。因此,每次读取 属性 时都会对其进行评估。甚至没有构造函数可以覆盖的支持字段。
我有时会在 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"。因此,每次读取 属性 时都会对其进行评估。甚至没有构造函数可以覆盖的支持字段。