Expression Bodied Members in C#

Expression Bodied Members in C# with Examples

In this article, I am going to discuss the Expression Bodied Members in C# with examples. Please read our previous article before proceeding to this article where we discussed the Generalized Async Return Types in C# with examples.

The Expression bodied Members in C# let you provide the implementation of a member in a better readable format. You can use an expression bodied members in C# whenever the logic for any supported members such as a method or property consists of a single expression. An expression body definition has the following general syntax:

member => expression; Where expression is a valid C# expression.

The Expression Bodied Members in C# was first introduced in C# 6 with only methods and properties. But with C# 7, several new members have been included in the list. The complete list of members is as shown below.

  1. Methods
  2. Properties
  3. Constructor
  4. Destructor
  5. Getters
  6. Setters
  7. Indexers

Let’s discuss each of these members one by one with examples.

Methods

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. For example, types that override the ToString method typically include a single expression that returns the string representation of the current object.

The below example defines an Employee class that overrides the ToString method with an expression body definition. It also defines a GetFullName method that returns the full name of the employee and again It also defines a DisplayName method that displays the name to the console. Note that the return keyword is not used in the ToString expression body definition.

public class Employee
{
    private string FirstName;
    private string LastName;

    public Employee(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public string GetFullName() => $"{FirstName} {LastName}";
    public override string ToString() => $"{FirstName} {LastName}";
    public void DisplayName() => Console.WriteLine(GetFullName());
}

class Program
{
    static void Main()
    {
        Employee employee = new Employee("Pranaya", "Rout");
        employee.DisplayName();
        Console.WriteLine(employee);
        Console.WriteLine("Press any key to exists");
        Console.ReadKey();
    }
}
OUTPUT:

Expression Bodied Members in C#

Note: This removes not only the curly brackets but also the return keyword. Return is implicit with a lambda expression.

Generally, expression bodied methods are more used than other members. They have the following characteristics.

  1. Expression bodied methods can specify all the accessibility operators i.e. public, protected, internal, private and protected internal.
  2. These can be declared virtual or abstract or can even override a base class method.
  3. Such methods can be static.
  4. Methods can even exhibit asynchronous behavior, if they return void, Task or Task<T>.

Constructors

An expression body definition for a constructor typically consists of a single assignment expression or a method call that handles the constructor’s arguments or initializes instance state.

The following example defines a Location class whose constructor has a single string parameter named name. The expression body definition assigns the argument to the Name property.

public class Location
{
    private string locationName;
    public Location(string name) => locationName = name;
    public string Name
    {
        get => locationName;
        set => locationName = value;
    }
}
class Program
{
    static void Main()
    {
        Location location = new Location("Mumbai");
        Console.WriteLine(location.Name);

        Console.WriteLine("Press any key to exists");
        Console.ReadKey();
    }
}
OUTPUT:

Expression Bodied Members in C#

Destructors

An expression body definition for a destructor typically contains cleanup statements, such as statements that release unmanaged resources.

The following example defines a destructor that uses an expression body definition to indicate that the destructor has been called.

public class Destroyer
{
    public override string ToString() => GetType().Name;
    ~Destroyer() => Console.WriteLine($"The {ToString()} destructor is executing.");
}

Property get

If you choose to implement a property get accessor yourself, you can use an expression body definition for single expressions that simply return the property value. Note that the return statement isn’t used.

The following example defines the Location.Name property whose property get accessor returns the value of the private locationName field that backs the property.

public class Location
{
    private string locationName;
    public Location(string name) => locationName = name;
    public string Name
    {
        get => locationName;
        set => locationName = value;
    }
}
class Program
{
    static void Main()
    {
        Location location = new Location("Mumbai");
        Console.WriteLine(location.Name);

        Console.WriteLine("Press any key to exists");
        Console.ReadKey();
    }
}

Read-only properties that use an expression body definition can be implemented without an explicit set statement. The following example defines a Location class whose read-only Name property is implemented as an expression body definition that returns the value of the private locationName field.

public class Location
{
    private string locationName;
    public Location(string name) => locationName = name;
    public string Name => locationName;
}
class Program
{
    static void Main()
    {
        Location location = new Location("Mumbai");
        Console.WriteLine(location.Name);

        Console.WriteLine("Press any key to exists");
        Console.ReadKey();
    }
}

The above code not only reduces the curly bracket but also writing the get accessor is not necessary. The code that’s generated from the compiler is the same.

Property set Expression Bodied Member in C#

If you choose to implement a property set accessor yourself, you can use an expression body definition for a single-line expression that assigns a value to the field that backs the property.

The following example defines the Location.Name property whose property set statement assigns its input argument to the private locationName field that backs the property.

public class Location
{
    private string locationName;
    public Location(string name) => locationName = name;
    public string Name
    {
        get => locationName;
        set => locationName = value;
    }
}
class Program
{
    static void Main()
    {
        Location location = new Location("Mumbai");
        Console.WriteLine(location.Name);
        location.Name = "Hyderabad";
        Console.WriteLine(location.Name);
        Console.WriteLine("Press any key to exists");
        Console.ReadKey();
    }
}

Indexers

Like properties, an indexer’s get and set accessors consist of expression body definitions if the get accessor consists of a single statement that returns a value or the set accessor performs a simple assignment.

The following example defines a class named Sports that includes an internal String array that contains the names of a number of sports. Both the indexer’s get and set accessors are implemented as expression body definitions.

public class Sports
{
    private string[] types = {"Cricket", "Baseball", "Basketball", "Football",
                              "Hockey", "Soccer", "Tennis","Volleyball" };

    public string this[int i]
    {
        get => types[i];
        set => types[i] = value;
    }
}
class Program
{
    static void Main()
    {
        Sports sports = new Sports();
        Console.WriteLine(sports[0]);
        Console.WriteLine(sports[2]);
        Console.WriteLine("Press any key to exists");
        Console.ReadKey();
    }
}

Expression bodied Members in C#: getters  and setters

Expression body getters and setters are also introduced in C# 7.0. They allow an expression to be used in the body of getters or setters. The example given below illustrates the same.

class Program
{
    static void Main(string[] args)
    {
        var obj = new ExprBodiedGettersnSetters();
        obj.EmpBasicSalaryList.Add(101, 1000);
        obj.EmpBasicSalaryList.Add(102, 1200);

        obj.EmpId = 101;

        Console.WriteLine($"The basic salary of EmpId {obj.EmpId} is: {obj.EmpBasicSalary}");
        obj.EmpBasicSalary = 1500;
        Console.WriteLine($"The updated basic salary of EmpId {obj.EmpId} is: {obj.EmpBasicSalary}");

        Console.WriteLine("Press any key to exist.");
        Console.ReadKey();
    }
}

class ExprBodiedGettersnSetters
{
    public Dictionary<int, double> EmpBasicSalaryList = new Dictionary<int, double>();
    public int EmpId { get; set; }
    public double EmpBasicSalary
    {
        ///Expression Bodied Getter  
        get => EmpBasicSalaryList[EmpId];
        ///Expression Bodied Setter  
        set => EmpBasicSalaryList[EmpId] = value;
    }
}
OUTPUT:

Expression Bodied Members in C#

Limitations of Expression Bodied Members in C#

Although expression bodied members in C# provide very clean syntax, they have some limitations. Let’s go through some of them and see how those can be addressed.

The Expression bodied members in C# don’t support a block of code. It supports only one statement with an expression, which is allowed. If you need to use more than one statements then you may use the regular methods or properties.

Branching statements (if..else, switch) are not allowed however if..else behavior can be achieved by ternary operator. For example, the statement given below can work.

public string FullName() => (middleName != null) ? firstName + ” ” + middleName + ” ” + lastName : firstName + ” ” + lastName;

Loop statements (i.e. for, foreach, while and do..while are not allowed) however in some cases, it can be replaced with LINQ queries. For example, both of the following methods (HundredNumbersList and HundredNumbersListWithExprBody) return the same result.

public IEnumerable<int> HundredNumbersList()

{

for (int i = 0; i < 100; i++)

yield return i;

}

public IEnumerable<int> HundredNumbersListWithExprBody() => from n in Enumerable.Range(0, 100)

select n;

Note: Lambda expressions can be written in short form without curly brackets when the statement consists of a single line. Lambda expressions can also be written in the long form where curly brackets and the return statement are needed. This longer syntax is not possible with expression bodied members in C#. If one code line is not enough, you can use the normal syntax with curly brackets, as is available since C# 1.0.

In the next article, I am going to discuss Throw expressions in C# with some examples.

SUMMARY

In this article, I try to explain Expression Bodied Members in C# step by step with some simple examples. I hope this article will help you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *