使用表达式主体覆盖自动属性

时间:2017-07-12 12:23:25

标签: c# roslyn c#-6.0

当使用抽象的getter-only自动属性然后用表达式body属性覆盖时,Roslyn编译器是否仍然使用支持字段?

根据我的理解,编译器将为自动属性创建一个支持字段,但它不会为表达式主体属性创建支持字段。

基础抽象类

public abstract class FooPage
{
     protected abstract string PageName { get; }
}

派生类

public class BarPage : FooPage
{
     protected override string PageName => "FooBar";
}

我想知道在这种情况下会发生什么。我在罗斯林的维基中找到了这个... https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#expression-bodies-on-property-like-function-members

但仍然不确定幕后究竟发生了什么。

1 个答案:

答案 0 :(得分:4)

首先,请注意:如果您对此类问题非常感兴趣,解决问题的最快方法是实际编译代码,然后使用ildasm或ILSpy等工具(在IL模式下)查看生成的代码。显然,这样的结果不能概括为对编译器应该做什么或必须做什么做出明确的陈述(只能通过标准来回答),而对于“我想知道”这些问题通常是否足够。

表达式主体属性只是写出方法的简写;它们永远不会导致生成支持字段。 BarPage可以像这样完整地写出来:

public class BarPage : FooPage
{
     protected override string PageName 
     {
         get { return "FooBar"; }
     }
}

这与FooPage中的属性如何实现无关,以及它是否具有支持字段。在您的示例中,它没有,因为这不是自动属性:

protected abstract string PageName { get; }

这是一个抽象属性,在引入只读自动属性之前就存在了。它看起来非常像一个自动财产,但它不是一个。以下不是合法的C#语法,但更好地反映了IL翻译:

protected string PageName 
{
    abstract get;
}

此处没有支持字段。另一方面,以下 是只读自动属性, 具有支持字段:

protected virtual string PageName { get; }

想象一下它看起来像这样(再次,不是合法的C#语法):

private readonly $PageNameBackingField;
protected string PageName 
{
    virtual get { return $PageNameBackingField; }
}

但是,至关重要的是,这仍然对BarPage中的实现没有任何影响,因为那里的getter不依赖于基本实现。如果您明确引用了base.PageName,则会发现如果基本属性为virtual,则此方法有效,如果基本属性为abstract,则会出错。您仍然无法直接访问支持字段(这很好;从客户端了解有关如何实现该属性的详细信息是完整的属性点。)