Stats

Contributors: 21 Tuesday, December 20, 2016
Licensed under: CC-BY-SA
Not affiliated with Stack Overflow
Rip Tutorial: riptutorial@gmail.com
Roadmap: roadmap

Expression-bodied function members

Download c# eBook

Example

Expression-bodied function members allow the use of lambda expressions as member bodies. For simple members, it can result in cleaner and more readable code.

Expression-bodied functions can be used for properties, indexers, methods, and operators.


Properties

public decimal TotalPrice => BasePrice + Taxes;

Is equivalent to:

public decimal TotalPrice
{
    get
    {
        return BasePrice + Taxes;
    }
}

When an expression-bodied function is used with a property, the property is implemented as a getter-only property.

View Demo


Indexers

public object this[string key] => dictionary[key];

Is equivalent to:

public object this[string key]
{
    get
    {
        return dictionary[key];
    }
}

Methods

static int Multiply(int a, int b) => a * b;

Is equivalent to:

static int Multiply(int a, int b)
{
    return a * b;
}

Which can also be used with void methods:

public void Dispose() => resource?.Dispose();

An override of ToString could be added to the Pair<T> class:

public override string ToString() => $"{First}, {Second}";

Additionally, this simplistic approach works with the override keyword:

public class Foo
{
    public int Bar { get; }

    public string override ToString() => $"Bar: {Bar}";
}

Operators

This also can be used by operators:

public class Land
{
    public double Area { get; set; }

    public static Land operator +(Land first, Land second) =>
        new Land { Area = first.Area + second.Area };
}

Limitations

Expression-bodied function members have some limitations. They can't contain block statements and any other statements that contain blocks: if, switch, for, foreach, while, do, try, etc.

Some if statements can be replaced with ternary operators. Some for and foreach statements can be converted to LINQ queries, for example:

IEnumerable<string> Digits
{
    get
    {
        for (int i = 0; i < 10; i++)
            yield return i.ToString();
    }
}
IEnumerable<string> Digits => Enumerable.Range(0, 10).Select(i => i.ToString());

In all other cases, the old syntax for function members can be used.

Expression-bodied function members can contain async/await, but it's often redundant:

async Task<int> Foo() => await Bar();  

Can be replaced with:

Task<int> Foo() => Bar();