New expression bodied members in C# 7.0
Although expression bodied members have been supported in C# few years there were still room for some new ones. C# 7.0 introduces expression bodied constructors, destructors, getters and setters. This blog post goes through all these new expression bodied members and shows how to use them. Also a little peek behind the compilator curtains is made.
Expression bodied constructors and destructors
There are many classes with simple constructor or destructor. Let’s take a primitive Product class as an example.
public class Product
{
public Guid Id { get; private set; }
public string Name { get; set; }
public Category Category { get; set; }
public Product(Guid id)
{
Id = id;
}
~Product()
{
Category = null;
}
}
For this class constructor and destructor can be written as simple one-liners in C# 7.0.
public class Product
{
public Guid Id { get; private set; }
public Category Category { get; private set; }
public Product(Guid id) => Id = id;
~Product() => Category = null;
}
Not much space to save but still something to keep code smaller.
Expression bodied getters and setters
Let’s see now how expression bodied accessor work. We use simple Person class and expect that there is primitive mechanism to track name history.
public class Person
{
private IDictionary<DateTime, string> _nameHistory;
// More code here ...
public string Name
{
get
{
return _nameHistory.LastOrDefault().Value;
}
set
{
_nameHistory.Add(DateTime.Now.Date, value);
}
}
}
We can make the Name property more compact by letting some air out from code.
public class Person
{
private IDictionary<DateTime, string> _nameHistory;
// More code here ...
public string Name
{
get { return _nameHistory.LastOrDefault().Value; }
set { _nameHistory.Add(DateTime.Now.Date, value); }
}
}
It’s shorter but there is still some noise we can avoid using C# 7.0.
public class Person
{
private IDictionary<DateTime, string> _nameHistory;
public string Name
{
get => _nameHistory.LastOrDefault().Value;
set => _nameHistory.Add(DateTime.Now.Date, value);
}
}
This is cleaner than previous version and therefore easier to read.
Expression bodied members after compiling
Now let’s put all new expression bodied members together to one class and see what happens to them after compiling. This is the class we will use for testing.
public class Person
{
private IDictionary<DateTime, string> _nameHistory;
public Person(IDictionary<DateTime, string> nameHistory) => _nameHistory = nameHistory;
~Person() => _nameHistory.Clear();
public string Name
{
get => _nameHistory.LastOrDefault().Value;
set => _nameHistory.Add(DateTime.Now.Date, value);
}
}
Here is what we get after compiling our test class. Take a careful look at it and see how many expression bodied members you see.
public class Person
{
private IDictionary<DateTime, string> _nameHistory;
public Person(IDictionary<DateTime, string> nameHistory)
{
base..ctor();
this._nameHistory = nameHistory;
}
~Person()
{
try
{
this._nameHistory.Clear();
}
finally
{
base.Finalize();
}
}
public string Name
{
get
{
return this._nameHistory.LastOrDefault<KeyValuePair<DateTime, string>>().Value;
}
set
{
this._nameHistory.Add(DateTime.Now.Date, value);
}
}
}
It seems like compiler threw us back to previous eras but it is not the case – it is a syntactic sugar we can use to write cleaner and more readable code.
Wrapping up
Expression bodied members were introduced back in years. C# 7.0 adds new ones for constructors, destructors and property accessors. Like previous ones, they are technically just a syntactic sugar for writing more readable code. Classes with small constructors and destructors will benefit from new expression bodied members. Also classes that have many properties with simple logic.
Pingback:The Morning Brew - Chris Alcock » The Morning Brew #2511
I definitely fail to feel excited about expression bodied properties. I honestly hate them. :-)
Wow, that’s a stupid feature.
People who post just to say that they hate a new language feature have very low IQs.