Auto-属性 被表达式正文覆盖

Auto-property overridden with expression body

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

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

创建一个支持字段

基础摘要class

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

派生class

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

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

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

首先,一般说明:如果您对此类问题非常感兴趣,解决它的最快方法是实际编译代码,然后使用 ildasm 或 ILSpy(在 IL 模式下)等工具查看生成的代码。显然,此结果不能概括为关于编译器应该做什么或必须做什么的明确陈述(只能由标准回答),但对于 "I wonder how" 问题,它通常就足够了。

表达式主体属性只是shorthand用于写出方法;它们永远不会导致生成支持字段。 BarPage 完全可以这样写:

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

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

protected abstract string PageName { get; }

这是一个抽象 属性,它在引入只读自动属性之前就已存在。它看起来很像 auto-属性,但它不是。以下不是合法的 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,则会报错.您仍然不会直接访问支持字段(这很好;将客户端与有关如何实现 属性 的详细信息隔离开来是属性的全部要点)。