getter-only auto属性和表达式body属性之间有什么区别?

时间:2015-01-12 21:24:20

标签: c# c#-6.0

在C#6中,您可以使用仅限getter的自动属性来简化属性的实现。例如,如果我实现了抽象Stream类:

public override bool CanRead { get; } = true;

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

public override bool CanRead => true;

两者之间有什么区别,我应该何时使用其中一种?

2 个答案:

答案 0 :(得分:60)

它们是两种不同东西的语法糖。前者初始化后备字段,并在字段初始化期间将其设置为赋值右侧的表达式。后者创建一个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时计算表达式。在bool的简单情况下,行为是相同的。然而,如果表达引起副作用,事情就会有所不同。考虑这个例子:

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和#34;印刷。每次调用属性的getter时,静态counter字段都会递增。但是,使用属性初始值设定项:

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

然后" 0,0,1,1和#34;因为表达式是在对象的构造函数中计算的,所以会打印出来。

答案 1 :(得分:3)

在我们的示例中描述的情况下,我曾经更喜欢:

public override bool CanRead { get; } = true;

但是今天我通知这个实现会导致支持字段的内存分配。所以,这个实现:bool CanRead => true;可以节省4个字节。