Quantcast
Channel: Falafel Software Blog » C# 6
Viewing all articles
Browse latest Browse all 7

Expression Bodied Methods and Properties – Day 11 – VS 2015 Series

$
0
0

More Syntactical Sugar

Syntactical Sugar comes in a wide range of flavors, nonetheless their goal is to decrease the level of noise in our code resulting in code where its intent is clear, easy to read, and distracting elements are minimized. Often they are tightly focused changes affecting a single code item.

MyOverlyLongClassnameExample exmpl = new MyOverlyLongClassnameExample();
// versus
var exmpl = new MyOverlyLongClassnameExample();

This is a typical example. The left hand side type reference is redundant. Replacing it with var doesn’t make the code any less clear and makes it much easier to scan.

Expression Bodied Methods and Properties, on the other hand, often streamline small blocks of code.

Let’s assume a simple Current Weather object which stores its various weather attributes in metric units. Its temperature attribute is stored as a property Temperature with Celsius (or possibly Kelvin)  as its unit of measure. However, the weather object should also provide its temperature attribute using Fahrenheit as the unit of measure. As we all learned as kids to convert C to F one first divides C by 5, then multiplies by 9, and finally adds 32;
Restated as an  expression: F = C  * 1/5 * 9 + 32.

Converting this simple expression to a method would result:

public Double ConvertCelsiustoFahrenheit(double celsius)
{
     return celsius  / 5 * 9 + 32
}

At least four lines of code for a simple short expression!

By using an Expression Body for this method one will safely eliminate the bulky method body thereby trimming four lines to a more appropriate one.

One item before we get into the details.

This feature only uses expressions, not statements. I am going to avoid defining these terms and instead offer a rough rule of thumb -hammer please-

If there's a semicolon,
     it's not an expression;
          it can't be used here.

Onward

Using lambda syntax we can implement our ConvertCelsiustoFahrenheit method using a one line Expression Bodied Method with an expression to provide the return value.

public double ConvertCelsiustoFahrenheit(double celsius) => celsius / 5 * 9 + 32;

Given that Temperature is a property of our object we’ll assume that temperature Fahrenheit, TemperatureF, should also be a property, albeit one without a backing field. For example:

public double TemperatureF { 
     get {
          return ;ConvertCelsiustoFahrenheit(Temperature);
          }
}

That’s better; but wait, there’s more;
Expression Bodies can also be used with read only properties.

public double TemperatureF => Temperature / 5 * 9 + 32;

Using a read read only property along with a getter to calculate the conversions resulted in a minimum of 5 lines of code. We are now providing the same functionality in a concise clear manner while using only one line.

Improving usefulness

Even though we are limited to expressions we can improve flexibility of the expression using the conditional operator, ?.

For illustration we will be using the following class, Person, which contains the various parts of a person’s name and a flag to indicate whether person’s fullname should be displayed SurName first instead of GivenName first.

public class Person
{
    public string GivenName { get; set; }
    public string MiddleName { get; set; }
        // AKA family name
    public string SurName { get; set; }       
        // Jr. Sr. III, Esq. M.D. etc. Exclude padding and separators
    public string NameSuffix { get; set; } 
        // Is fullname is expressed SurName MiddleName GivenName 
        // e.g. Chinese, Indian
    public bool BeginWithSurName { get; set; }
    
    public Person() { }

    public Person(
        string givenName,
        string middleName,
        string surName,
        string nameSuffix,
        bool beginWithSurName
    )
    {
        this.GivenName = givenName;
        this.MiddleName = middleName;
        this.SurName = surName;
        this.NameSuffix = nameSuffix;
        this.BeginWithSurName = beginWithSurName;
    }
}

To our Person let’s add a FullName property to return a properly formatted string assembled from the various xxxName properties

// read only property using single expression getter calling a method
public string FullName => GetFullName();
    
private string GetFullName()
{
    if (BeginWithSurName)
        return String.Format("{0} {1} {2}, {3}", 
                              SurName, MiddleName, GivenName, NameSuffix);
    else
        return String.Format("{0} {1} {2}, {3}", 
                              GivenName, MiddleName, SurName, NameSuffix);
}

If a Person doesn’t have a middle name our formatting will include an extra space; without a suffix the FullName will end with a superfluous comma and space. Let’s fix that with an Expression Bodied helper method

private string PrefixWhenNotEmpty(string val, string prefix) => String.IsNullOrEmpty(val) ? val : prefix + val;

To our method we pass a string and a prefix. If the prefix is empty the string is returned and if not the combination of prefix + string is returned. We’d use in this manner:

return String.Format("{0}{1}{2}{3}", 
              GivenName,
              PrefixWhenNotEmpty(MiddleName, " "), 
              PrefixWhenNotEmpty(SurName, " "), 
              PrefixWhenNotEmpty(NameSuffix, ", "));

Much cleaner although we still have that if else clause in GetFullName

return String.Format("{0}{1}{2}{3}",
   BeginWithSurName ? SurName : GivenName,
   PrefixWhenNotEmpty(MiddleName, " "),
   PrefixWhenNotEmpty( (BeginWithSurName ? GivenName : SurName), " "), 
   PrefixWhenNotEmpty(NameSuffix, ", "));

Note the inner parentheses on line 4. This is a case where we are nesting an expression, but still avoiding the dreaded STATEMENT. I find this last example a bit excessive and a tad awkward to read, but it serves to show that Expression bodies can be used to perform quite a range of tasks if a little care is taken.
In one last example of silly let’s collapse is all to a Expression Bodied property and the PrefixWhenNotEmpty helper method, and one more new feature in C# to be covered soon.

public string FullName => 
$"{(BeginWithSurName ? SurName : GivenName)}{PrefixWhenNotEmpty(MiddleName, " ")}{(BeginWithSurName ? PrefixWhenNotEmpty(GivenName, " ") : PrefixWhenNotEmpty(SurName, " "))}{PrefixWhenNotEmpty(NameSuffix, ", ")}";

Embarassing as this example truly is, it does work and work properly.

The post Expression Bodied Methods and Properties – Day 11 – VS 2015 Series appeared first on Falafel Software Blog.


Viewing all articles
Browse latest Browse all 7

Latest Images

Trending Articles





Latest Images