Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read-Only Auto-Property for Simple Types: Initializer VS Expression Body Getter

In C# 6.0, the new syntax let us write read-only auto-properties with using an initializer:

public bool AllowsDuplicates { get; } = true;

Likewise, we can write it using an expression body getter:

public bool AllowsDuplicates => true;

For simple types, these two should have the same effect: a read-only auto-property that returns true.

But is one of them preferred over the other? I suspect that the former uses a backing field:

private readonly bool _backingField = true;
public bool AllowsDuplicates {
    get {
        return _backingField;
    }
}

Whereas the latter is turned into something like:

public bool AllowsDuplicates {
    get {
        return true;
    }
}

Is that right, or is the compiler smarter than this?

like image 361
Mikkel R. Lund Avatar asked May 02 '16 20:05

Mikkel R. Lund


People also ask

What is an expression-bodied method?

An expression-bodied method consists of a single expression that returns a value whose type matches the method's return type, or, for methods that return void , that performs some operation.

What is Auto property initializer in C#?

C# auto-initialize property is a feature, introduced in 6.0. It allows us to initialize properties without creating a constructor. Now, we can initialize properties along with declaration. In early versions, constructor is required to initialize properties.

Which is correct syntax for expression-bodied function?

The Syntax of expression body definition is, member => expression; where expression should be a valid expression and member can be any from above list of type members.

When to use auto implemented properties?

using properties allows you to encapsulate your data better. and when you just want to have a field accessible without any logic in you class then you can use automatic properties.


1 Answers

I suspect that the former uses a backing field

The auto-property initializer does in fact creating a backing field! You can throw this in ILSpy and see it in the output:

public class One
{
    public bool AllowsDuplicates
    {
        [CompilerGenerated]
        get
        {
            return this.<AllowsDuplicates>k__BackingField;
        }
    }

    public One()
    {
        this.<AllowsDuplicates>k__BackingField = true;
        base..ctor();
    }
}

public class Two
{
    public bool AllowsDuplicates
    {
        get
        {
            return true;
        }
    }
}

But is one of them preferred over the other?

For the specific example in the question, the auto-property would allow a constructor to ask for a bool and assign it. The second style would not. If the intent is to use it as a "default value" which can be modified once during construction, then an auto-property is the right choice.

class Test
{
    // Could assign this in the second constructor
    public bool AllowsDuplicates { get; } = true;

    // Cannot assign this in the second constructor
    public bool AllowsDuplicates => true;

    public Test()
    {
        // Default value used
    }

    public Test(bool value)
    {
        AllowsDuplicates = value;
    }
}

I've seen expression bodied syntax win out most when it's a cover for a small function that is utilized as a property. A struct in Eric Lippert's dedoublifier has a nice example of this:

public DoubleHelper(double d)
{
    this.RawBits = (ulong)BitConverter.DoubleToInt64Bits(d);
}

public ulong RawBits { get; }
// RawSign is 1 if zero or negative, 0 if zero or positive
public int RawSign => (int)(RawBits >> 63);
public int RawExponent => (int)(RawBits >> 52) & 0x7FF;
public long RawMantissa => (long)(RawBits & 0x000FFFFFFFFFFFFF);
public bool IsNaN => RawExponent == 0x7ff && RawMantissa != 0;
public bool IsInfinity => RawExponent == 0x7ff && RawMantissa == 0;
public bool IsZero => RawExponent == 0 && RawMantissa == 0;
public bool IsDenormal => RawExponent == 0 && RawMantissa != 0;

There's one value which is assigned in the constructor, and the rest are property values which are computed based off of it.

like image 136
Will Ray Avatar answered Nov 02 '22 18:11

Will Ray