简体   繁体   中英

Auto-property overridden with expression body

When using abstract getter-only auto-properties that are then overridden with an expression body property, does the Roslyn compiler still create an use the backing field?

From my understanding, the compiler will create a backing field for an auto-property, but it will not create a backing field for an expression body property.

Base abstract class

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

Derived class

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

I am wondering what happens in this scenario. I found this in Roslyn's wiki.. https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#expression-bodies-on-property-like-function-members

but still not sure what actually happens under the covers.

First, a general note: if you are very interested in such matters, the quickest way to resolve it is to actually compile code, and then use a tool like ildasm or ILSpy (in IL mode) to look at the generated code. Obviously the result of this cannot be generalized to make definite statements about what the compiler should do or must do (that can only be answered by standards), but for "I wonder how" questions it often suffices.

Expression body properties are simply shorthand for writing out methods; they will never cause a backing field to be generated. BarPage could be written out in full like this:

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

This is irrespective of how the property is implemented in FooPage , and whether it has a backing field there or not. In your example, it does not, because this isn't an auto-property:

protected abstract string PageName { get; }

This is an abstract property, which existed before read-only auto-properties were introduced. It looks very much like an auto-property, but it isn't one. The following isn't legal C# syntax but reflects the IL translation better:

protected string PageName 
{
    abstract get;
}

No backing field here. On the other hand, the following is a read-only auto-property and does have a backing field:

protected virtual string PageName { get; }

Imagine it looking like this (again, not legal C# syntax):

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

But, crucially, this still has no influence at all on the implementation in BarPage , because the getter there doesn't rely on the base implementation. If you referenced base.PageName explicitly, you would find that this works if the base property is virtual , and will give an error if the base property is abstract . You'd still not be accessing the backing field directly (which is good; insulating clients from the details about how the property is implemented is the whole point of properties).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM