With C# 8 on our doorstep, I figure it is a good time to reflect on recent additions to the language that have come before. There are some great improvements you may have missed, some that I really enjoy using, and some I consider have reached canonical usage status that I think are all worth some reflection.

We already had a look at how we can use Expression body members in C# 6. In C# 7.0, this has been extended further to include constructors, finalizers, and get and set accessors on properties and indexers.

// The old way:
public class Gadget<T>
{    
    // A property with a custom get implementation
    private int _dateAsTicks;
    public DateTime myValue
    {
        get
        {
            return new DateTime(_dateAsTicks);
        }
        set
        {
            _dateAsTicks = value.Ticks;
        }
    }
    
    // A standard constructor
    public Gadget(int ticks)
    {
        _dateAsTicks = ticks;
    }
    
    public ~Gadget()
    {
        // just imagine this actually needed a destructor
        _dateAsTicks = 0;
    }
    
    private T[] _items = new T[100];
    public T this[int i]
    {
        get
        {
            return _items[i];
        }
        set
        {
            _items[i] = value;
        }
    }
}

And now with lambdas:

public class Gadget<T>
{ 
    private int _dateAsTicks;
    public DateTime myValue
    {
        get = > new DateTime(_dateAsTicks);
        set => _dateAsTicks = value.Ticks;
    }
    
    // A readonly prop version would look like this
    // public DateTime myValue = > new DateTime(_dateAsTicks);
    
    // A standard constructor
    public Gadget(int ticks) => _dateAsTicks = ticks
    
    public ~Gadget() => _dateAsTicks = 0;
 
    private T[] _items = new T[100];
    public T this[int i]
    {
        get => _items[i];
        set => _items[i] = value;
    }
    
    // If it were readonly it could look like this:
    // public T this[int i] => _items[i];
}

Much like the last instalment, this is a pretty consistent and straight-forward transformation into lambdas, just with an increased scope of application.

Also, did you know that expression body members are binary compatible? It is worth knowing. What this means is that if you have a method, it doesn't matter if you compile with a method body or an expression body member, they both produce the same binary signature, and anything that links to your DLL won't know the difference. This means you can change your code back and forward and not have to worry about breaking binary compatibility. Code compiled against a version that used a method body will still work against it when you change it to a member body expression.

Just bear in mind that changes between methods and properties, and changes of method signatures are not binary compatible changes.