一尘不染

纯吸气剂自动属性和表达式主体属性之间有何区别?

c#

在C#6中,您可以通过使用仅吸气剂自动属性来简化实现属性。例如,如果我正在实现抽象Stream类:

public override bool CanRead { get; } = true;

但是,我也可以使用C#6中新增的表达式主体来编写它:

public override bool CanRead => true;

两者之间有什么区别,什么时候应该使用另一个?


阅读 301

收藏
2020-05-19

共1个答案

一尘不染

它们是两种不同事物的语法糖。前者初始化一个后备字段,并在字段初始化期间将其设置为赋值右侧的表达式。后者创建一个get与表达式完全相同的表达式。

public override bool CanRead { get; } = true;

相当于

private readonly bool __backingFieldCanRead = true;

public override bool CanRead
{
    get
    {
        return __backingFieldCanRead;
    }
}

这个

public override bool CanRead => true;

相当于

public override bool CanRead
{
    get
    {
        return true;
    }
}

他们的行为有所不同。第一种情况在创建对象并初始化字段时设置属性的值,另一种情况在每次调用属性的getter时都会评估表达式。在布尔的简单情况下,行为是相同的。但是,如果该表达式引起副作用,则情况有所不同。考虑以下示例:

class Program
{
    static void Main(string[] args)
    {
        var fooBar1 = new FooBar();
        Console.WriteLine(fooBar1.Baz);
        Console.WriteLine(fooBar1.Baz);
        var fooBar2 = new FooBar();
        Console.WriteLine(fooBar2.Baz);
        Console.WriteLine(fooBar2.Baz);
    }
}

public class FooBar
{
    private static int counter;
    public int Baz => counter++;
}

在此,打印“ 0、1、2、3”。counter每次调用属性的getter时,静态字段都会增加。但是,使用属性初始化程序:

public int Baz { get; } = counter++;

然后打印“ 0,0,1,1”,因为表达式是在对象的构造函数中求值的。

2020-05-19