Expression-bodied members provide a minimal and concise syntax to define properties and methods. It helps to eliminate boilerplate code and helps writing code that is more readable. The expression-bodied syntax can be used when a member’s body consists only of one expression. It uses the =>(fat arrow) operator to define the body of the method or property and allows getting rid of curly braces and the return keyword. The feature was first introduced in C# 6.
Expression-bodied Methods
In C#, a method is a collection of statements that perform a given task and return the result to the caller. Often times, methods end up containing only a single statement. For example, consider the following code:
int GetRectangleArea(int length, int breadth)
{
return length * breadth;
}
The above method only consists of a single return statement. Using expression-bodied syntax, the above method can be rewritten as follows:
int GetRectangleArea(int length, int breadth) => length * breadth;
Notice, the absence of the curly braces and the return statement. Instead of curly braces, the => operator has been used. The expression that follows after the return statement is written right after the => operator.
Syntax
[access-modifier] [qualifiers] return-type MethodName([parameters]) => expression;
Example
The following example defines a Boolean method called IsEven() that returns true if the number passed to it is even, otherwise, the method returns false. The IsEven() method uses expression-bodied syntax.
C#
using System;
class GFG{
public static bool IsEven( int number) => number % 2 == 0;
public static void Main()
{
int n = 10;
if (IsEven(n))
{
Console.WriteLine( "{0} is even" , n);
}
else
{
Console.WriteLine( "{0} is odd" , n);
}
}
}
|
Expression-bodied Void Methods
Void methods are those methods that do not contain a return statement and consist only of a single statement can also use expression-bodied syntax. For instance, the following method:
void PrintName(string name)
{
Console.WriteLine($"The name is {name}");
}
can be written with expression-bodied syntax as follows:
void PrintName(string name) => Console.WriteLine($"The name is {name}");
Expression-bodied Properties
Property accessors also can have only one statement. With expression-bodied properties, such property definitions can be simplified.
1. Read-only Properties
Read-only properties are properties that only have a get accessor, like the following:
public int Name
{
get
{
return "Geeks For Geeks";
}
}
Using expression-bodied syntax, the property can be defined as follows:
public int Name => "Geeks For Geeks";
Syntax
[access-modifier] [qualifier] type PropertyName => expression;
Example
The following example defines a class called Square with a constructor that accepts the length of the side of the square. Once the side is set in the constructor, it cannot be modified because the public Side property is read-only. Also, the side field is private and cannot be accessed from outside the class.
C#
using System;
public class Square
{
private int side;
public Square( int side)
{
this .side = side;
}
public int Side => side;
}
class GFG{
public static void Main()
{
var square = new Square(4);
Console.WriteLine($ "Side is {square.Side}" );
}
}
|
2. Non-Read only Properties
Since C# 7, non-read-only properties can also have expression-bodied get and set accessors. In the following Person class, the Name property defines both get and set accessors each with only one statement:
public class Person
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
This can be simplified by using expression-bodied accessors:
public class Person
{
private string name;
public string Name
{
get => name;
set => name = value;
}
}
Syntax
[access-modifier] [qualifiers] [type] PropertyName
{
get => expression;
set => expression;
}
Example
The code below defines a Square class like the above example but here, the Side property also has a set accessor. Also, an object initializer has been used instead of a constructor to provide the initial value for the Side property:
C#
using System;
public class Square
{
private int side;
public int Side
{
get => side;
set => side = value;
}
}
class GFG{
public static void Main()
{
var square = new Square{Side = 4};
Console.WriteLine($ "Side is {square.Side}" );
square.Side = 10;
Console.WriteLine($ "Side is now {square.Side}" );
}
}
|
Output
Side is 4
Side is now 10
Expression-bodied Constructors and Destructors
The expression-bodied syntax has also been extended to be used with constructors and destructors / Finalizers. If either of these methods contains only a single statement, they can be defined as expression-bodied.
Syntax
[access-modifier] ClassName([parameters]) => expression;
~ClassName() => expression;
Example
In the example that follows, the Square class defines a constructor and destructor each of which contains an expression-bodied definition:
C#
using System;
public class Square
{
private int side;
public Square( int side) => this .side = side;
~Square() => Console.WriteLine( "Square's Destructor" );
public int Side => side;
}
class GFG{
public static void Main()
{
var square = new Square(4);
Console.WriteLine($ "Side is {square.Side}" );
}
}
|
Output
Side is 4
Square's Destructor
Expression-bodied Indexers
Similar to properties, indexers accessors can also be expression-bodied. Indexer definitions follow the same conventions as properties which implies that read-only indexers can be defined without specifying the accessor and read and write accessors require the name of the accessor.
Syntax
[access-modifier] [qualifiers] return-type this[ [parameters] ] => expression;
[access-modifier] [qualifiers] return-type this [ [parameters] ]
{
get => expression;
set => expression;
}
Example
The following class ProgrammingLangs defines a string array language of programming languages and also defines an indexer that forwards the indexes to the languages array and returns the element(language) at that index. The indexer is read-only, therefore the languages in the array cannot be modified outside the class.
C#
using System;
public class ProgrammingLangs
{
private string [] languages =
{
"C#" ,
"C" ,
"C++" ,
"Python" ,
"Java"
};
public string this [ int idx] => languages[idx];
}
class GFG{
public static void Main()
{
var langs = new ProgrammingLangs();
Console.WriteLine(langs[0]);
Console.WriteLine(langs[2]);
Console.WriteLine(langs[3]);
}
}
|
Expression-bodied Operator Functions
Just like how ordinary methods with a single statement can be expression-bodied, operator method definitions can also be expression-bodied if their body consists of a single statement.
Syntax
[access-modifier] static operator [operator-symbol] ([parameters]) => expression;
Example
The following example implements a class Complex that represents the real and imaginary part of a complex number and also defines the binary + operator to allow the addition of two Complex objects. The operator+ function is expression-bodied.
C#
using System;
public struct Complex
{
public int Real{ get ; set ;}
public int Imaginary{ get ; set ;}
public Complex( int real, int imaginary)
{
Real = real;
Imaginary = imaginary;
}
public static Complex operator + (
Complex c1, Complex c2) =>
new Complex(c1.Real + c1.Real,
c1.Imaginary + c2.Imaginary);
public override string ToString() =>
$ "({Real}) + ({Imaginary}i)" ;
}
class GFG{
public static void Main()
{
var a = new Complex(3, 2);
var b = new Complex(1, 2);
var result = a + b;
Console.WriteLine($ "{a} + {b} = {result}" );
}
}
|
Output:
(3) + (2i) + (1) + (2i) = (6) + (4i)
Last Updated :
12 Oct, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...