Working With Expression Bodied Members In C# 7.0

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 member must have a name, return type and returned expression.

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

Expression body methods & properties

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

  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             Console.WriteLine($"Using expression bodied method:\n{new ExprBodiedMethodnProp().EmployeeDetail()}");  
  6.             Console.WriteLine($"\nUsing expression bodied properties:\n{new ExprBodiedMethodnProp().EmployeeProp}");  
  7.         }  
  8.     }  
  9.   
  10. class ExprBodiedMethodnProp  
  11.     {  
  12.         int empId { get; } = 101;  
  13.         string empName { get; } = "Prakash";  
  14.         string empAddress { get; } = "Kondapur, Hyderabad - 500084";  
  15.         double empBasicSalary { get; } = 1000;  
  16.         /// <summary>  
  17.         /// Expression bodied method  
  18.         /// </summary>  
  19.         public double empHRA() => (empBasicSalary * 40) / 100;  
  20.         /// <summary>  
  21.         /// Expression bodied property  
  22.         /// </summary>  
  23.         public double empHRAProp => (empBasicSalary * 40) / 100;  
  24.         /// <summary>  
  25.         /// Expression bodied method  
  26.         /// </summary>  
  27.         public string EmployeeDetail() => $"EmpId: {empId}\nEmpName: {empName}\nEmpAddress: {empAddress}\nEmpHRA: {empHRA()}";  
  28.         /// <summary>  
  29.         /// Expression bodied property  
  30.         /// </summary>  
  31.         public string EmployeeProp => $"EmpId: {empId}\nEmpName: {empName}\nEmpAddress: {empAddress}\nEmpHRA: {empHRAProp}";  
  32.     }  

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 operator 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.

  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5. Console.WriteLine($"Using expression bodied constructor and destructor:\n{new ExprBodiedConsnDes().EmployeeDetail()}");  
  6.         }  
  7.     }  
  8.   
  9. class ExprBodiedConsnDes  
  10.     {  
  11.         int empId { get; } = 101;  
  12.         string empName { get; } = "Prakash";  
  13.         string empAddress { get; } = "Kondapur, Hyderabad - 500084";  
  14.         double empBasicSalary { get; }  
  15.         /// <summary>  
  16.         /// Expression bodied constructor  
  17.         /// </summary>  
  18.         public ExprBodiedConsnDes() => empBasicSalary = 1000;  
  19.   
  20.         /// <summary>  
  21.         /// Expression bodied destructor  
  22.         /// </summary>  
  23.         ~ExprBodiedConsnDes() => Console.WriteLine("\nI am a destructor of ExprBodiedConsnDes class");  
  24.         public string EmployeeDetail() => $"EmpId: {empId}\nEmpName: {empName}\nEmpAddress: {empAddress}\nEmpBasicSalary: {empBasicSalary}";  
  25.     }  

Output

Output

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

Expression body getters & setters

Expression body getters and setters are also introduced in the C# 7.0. They allow an expression to be used in the body of getters or setters.

The example given below illustrates the same.

  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5. var obj = new ExprBodiedGettersnSetters();  
  6.             obj.EmpBasicSalaryList.Add(101, 1000);  
  7.             obj.EmpBasicSalaryList.Add(102, 1200);  
  8.             obj.EmpId = 101;  
  9.             Console.WriteLine($"The basic salary of EmpId {obj.EmpId} is: {obj.EmpBasicSalary}");  
  10.             obj.EmpBasicSalary = 1500;  
  11.             Console.WriteLine($"The updated basic salary of EmpId {obj.EmpId} is: {obj.EmpBasicSalary}");  
  12.         }  
  13.     }  
  14.   
  15. class ExprBodiedGettersnSetters  
  16.     {  
  17.         public Dictionary<intdouble> EmpBasicSalaryList = new Dictionary<intdouble>();  
  18.         public int EmpId { get; set; }  
  19.         public double EmpBasicSalary  
  20.         {  
  21.             ///Expression Bodied Getter  
  22.             get => EmpBasicSalaryList[EmpId];  
  23.             ///Expression Bodied Setter  
  24.             set => EmpBasicSalaryList[EmpId] = value;  
  25.         }  
  26.     }  

Output

Output

You can see that we have used both Expression Bodied Getter and Setter inside 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 doesn’t support block of code. It supports only one statement with an expression, which is allowed. If you need to use more than one statements, 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.
    1. 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) returns the same result.
    1. public IEnumerable<int> HundredNumbersList()  
    2.         {  
    3.             for (int i = 0; i < 100; i++)  
    4.                 yield return i;  
    5.         }  
    6.   
    7.         public IEnumerable<int> HundredNumbersListWithExprBody() => from n in Enumerable.Range(0, 100)  
    8.             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 limitation 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 for your comments/suggestions.

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