Working With Expression Bodied Members In C# 7.0

Introduction

I am here to continue the series related to C# 7.0 features. Today, we will be going through existing and newly introduced expression-bodied members and will demonstrate their uses in an easy way.

Expression bodied members

Expression-bodied members are developed on top of anonymous types and lambda expressions and are not totally new to C# 7.0.

We already have methods and properties-based expression-bodied members in C# 6.0. However, several new members have been introduced in C# 7.0, as shown below.

  • Expression-bodied constructor.
  • Expression-bodied destructor.
  • Expression-bodied getters.
  • Expression-bodied setters.

Some of the characteristics of expression-bodied members are given below.

  • They provide clean and crisp syntax.
  • Expression-bodied members must have a name, return type, and returned expression.

Before jumping to the new members, let’s quickly review the existing ones.

Expression body methods & properties

Let’s look at the examples directly to understand how they can be used.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine($"Using expression bodied method:\n{new ExprBodiedMethodnProp().EmployeeDetail()}");
        Console.WriteLine($"\nUsing expression bodied properties:\n{new ExprBodiedMethodnProp().EmployeeProp}");
    }
}
class ExprBodiedMethodnProp
{
    int empId { get; } = 101;
    string empName { get; } = "Prakash";
    string empAddress { get; } = "Kondapur, Hyderabad - 500084";
    double empBasicSalary { get; } = 1000;
    /// <summary>
    /// Expression bodied method
    /// </summary>
    public double empHRA() => (empBasicSalary * 40) / 100;
    /// <summary>
    /// Expression bodied property
    /// </summary>
    public double empHRAProp => (empBasicSalary * 40) / 100;
    /// <summary>
    /// Expression bodied method
    /// </summary>
    public string EmployeeDetail() => $"EmpId: {empId}\nEmpName: {empName}\nEmpAddress: {empAddress}\nEmpHRA: {empHRA()}";
    /// <summary>
    /// Expression bodied property
    /// </summary>
    public string EmployeeProp => $"EmpId: {empId}\nEmpName: {empName}\nEmpAddress: {empAddress}\nEmpHRA: {empHRAProp}";
}

Output

Output

As you can see in the above code, empHRA and EmployeeDetail methods are expression-bodied methods whereas empHRAProp and EmployeeProp are expression-bodied properties.

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

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

Expression body Constructors & Destructors

These are the new members introduced in C# 7.0. They allow an expression to be used in the constructor and destructor as well. The example given below explains the same.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine($"Using expression bodied constructor and destructor:\n{new ExprBodiedConsnDes().EmployeeDetail()}");
    }
}
class ExprBodiedConsnDes
{
    int empId { get; } = 101;
    string empName { get; } = "Prakash";
    string empAddress { get; } = "Kondapur, Hyderabad - 500084";
    double empBasicSalary { get; }
    /// <summary>
    /// Expression bodied constructor
    /// </summary>
    public ExprBodiedConsnDes() => empBasicSalary = 1000;
    /// <summary>
    /// Expression bodied destructor
    /// </summary>
    ~ExprBodiedConsnDes() => Console.WriteLine("\nI am a destructor of ExprBodiedConsnDes class");
    public string EmployeeDetail() => $"EmpId: {empId}\nEmpName: {empName}\nEmpAddress: {empAddress}\nEmpBasicSalary: {empBasicSalary}";
}

Output

Output

As you can see in the code above, ExprBodiedConsnDes() is defined as an expression-bodied constructor, and ~ExprBodiedConsnDes() is the expression-bodied destructor.

Expression body getters & 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}");
    }
}
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

Output

You can see that we have used both Expression Bodied Getter and Setter inside the EmpBasicSalary property.

Limitations of expression-bodied members and beyond

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

  • Expression-bodied members 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 statement, 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;
    

Conclusion

In this article, we have gone through and learned the things given below.

  • What are expression-bodied members?
  • What are the existing (C# 6.0) and new expression-bodied members (C# 7.0)?
  • How to work with an existing expression body methods & properties?
  • How to work with new expression body constructors & destructors?
  • How to work with new expression body getters & setters?
  • What are the limitations of using expression-bodied members, and how to address them?

You can also download the attached demo project (ExprBodiedMember.zip).

Hope you have liked the article. Look forward to your comments/suggestions.

If you also want to go through the previous parts of the series, the links are given below.


Similar Articles