Expression-bodied members in properties

21/08/2023
C#.NET

Are these two expressions the same?

public class MyClass
{
    public int A { get; } = Random.Shared.Next(1000);
    public int B => Random.Shared.Next(1000);
}

The short answer is, no they are not! If we run the example:

var m = new MyClass();
Console.WriteLine(m.A);
Console.WriteLine(m.A);

Console.WriteLine(m.B);
Console.WriteLine(m.B);


public class MyClass
{
    public int A { get; } = Random.Shared.Next(1000);
    public int B => Random.Shared.Next(1000);
}

We get the following result:

803
803
912
431

So { get; } = evaluates the expression on etime and puts it into the backing field, whereas the lambda expression "calls" the member on every access. The lowered code shows this pretty obviously:

public class MyClass
{
    [CompilerGenerated]
    private readonly int <A>k__BackingField = Random.Shared.Next(1000);

    public int A
    {
        [CompilerGenerated]
        get
        {
            return <A>k__BackingField;
        }
    }

    public int B
    {
        get
        {
            return Random.Shared.Next(1000);
        }
    }
}
9
An error has occurred. This application may no longer respond until reloaded. Reload x