I’m going to walk through an example that we can build up and improve with a number of the new C# 7 features.

Lets say we have a method that takes an object and tries to convert it to a number. There are two ways it does this

  • If it’s an int then the object is the number.
  • If it’s a string then it will try to convert it using int.TryParse.
  • If it’s anything else then return null.

If we were writing this in C#6 it might look like this

public int? FindNumber(object o)
{
    int? result = null;
    if (o is int)
        result = (int)o;
    if (o is string)
    {
        int number;
        if (int.TryParse(o.ToString(), out number))
            result = number;
        }
    return result;
}

Pattern Matching & Output Parameters

With C# 7 we can use the is statement to test for shape and assign it to a variable for example

if(o is int i)
    result = i;

In the above example if o in an int it will be casted to the local variable i which is created at that point.

We can then take that further by putting an or statement in for the string check

if(o is int i || (o is string s && int.TryParse(s,out i)))
{
    result = i;
}

You may also notice another C# 7 feature in the code above. That is the out parameter wasn’t declared before it was used, In C#7 it doesn’t need to be.

Given the new features our original method can now look like this

public int? FindNumber(object o)
{
    if(o is int i || (o is string s && int.TryParse(s,out i)))
        return i;
    return null;
}

For examples sake let’s package this method up into a class that we’ll throw some other random stuff into and lets assume the constructor takes the object we’re operating on.

public class BoxOfRandomStuff
{
    private object obj;

    public BoxOfRandomStuff(object o)
    {
        obj = o;
    }

    public int? FindNumberPatternMatching()
    {
        if (obj is int i || (obj is string s && int.TryParse(s, out i)))
            return i;
        return null;
    }
}

From here we can look at the next new feature, Constructor expression bodies. We’ve had expression bodies in C#6 for readonly properties and methods but we’ve now got them for read/write properties, constructors and deconstructors. With that the constructor in the above class can be rewritten as…

public BoxOfRandomStuff(object o) => obj = 0;

Tuples

Lets say we want a method in our new class that returns the current time in 3 parts hours, minutes and seconds. We could create a class to represent this but in this case we only want to use it in one place and a class may be over kill and that would ruin the example. First lets see how we’d do this in C#6

public void GetCurrentTime(out int hours, out int minutes, out int seconds)
{
    var time = DateTime.Now;
    hours = time.Hour;
    minutes = time.Minute;
    seconds = time.Second;
}

Which we would call like…

int hour;
int minute;
int second;
test.GetCurrentTime(out hour, out minute, out second);

Now lets take the next step and remove the out parameter declarations as they’re not needed in C#7

test.GetCurrentTime(out hour, out minute, out second);

Next lets look at the new Tuple syntax. For this you may need to install the System.Tuple nuget package from Microsoft.

public (int hours, int minutes, int seconds) GetCurrentTime()
{
    var time = DateTime.Now;
    return (time.Hour, time.Minute, time.Second);
}

Which can be called like this

var timeTuple = test.GetCurrentTime();
Console.WriteLine($"{timeTuple.hours}:{timeTuple.minutes}:{timeTuple.seconds}");

In this case I named the output in the return type of the method but I could have just done (int,int,int) and then they could be referenced by their position e.g Item1, Item2, etc.

I find this much cleaner than out parameters and although I rarely use them anyway I can’t see myself ever picking them over a named Tuple now.

As a finishing note everything above is just to demo the new features and is in no way best practice.