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

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

public int Number { get; } = 0 public int Number => 0; 

有人可以告诉我,如果这两者之间有任何区别。 他们如何performance? 他们都是只读吗?

是的,它们都是只读的,但是有区别。 第一个是在构造函数执行前有一个初始化为0的后台字段。 您只能在构造函数中更改该值,就像常规的只读字段一样。 getter本身只是返回字段的值。

在第二个,每次getter只返回0,没有涉及的领域。

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

第一个版本

 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; 

如果创build单个对象,则其CreationTime属性始终会给出相同的结果 – 因为它存储在只读字段中,在对象构造上初始化。 但是,每次访问CurrentTime属性时,都会导致对DateTime.UtcNow进行评估,因此您将得到一个潜在的不同结果。

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

用DateTime属性可以更好地看到这一点:

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

Start属性保持返回同一时间(创build实例时),而Now则更改为反映当前时间。

说明

第一个版本(“开始”)提供了一个可能被构造函数覆盖的初始值。 所以这只被评估一次。
第二个版本(“现在”)提供了这个属性的“getter”的expression式。 所以每次读取属性时都会对其进行评估。 甚至没有构造函数可以覆盖的后台字段。

这些是C#6语言function。

第一个例子

 public int Number { get; } = 0 

第一个例子是一个只有getter的自动属性 。 只有getter属性的auto属性的后台字段被隐式声明为readonly。

第二个例子

 public int Number => 0; 

第二个例子是类属性函数成员的expression式 。 请注意,没有任何get关键字:它是通过使用expression式主体语法来隐含的。

两者都是只读的。