DEV Community

Cover image for Nifty and useful features in C# 7
Andreas Rein
Andreas Rein

Posted on • Updated on

Nifty and useful features in C# 7

This article was first published on Steemit.

The seventh version of the enjoyable programming language C# is not a big release, but it comes with some nifty features and some really sweet syntax lollies. This post will be an overview of the most useful features in my opinion.

Tuples

Tuples have been around for quite some time, but it has not been integrated into the language before now. A tuple is a data structure that has a specific number and sequence of elements. You can now declare methods that have multiple return values.

If you think you have to pass in sum and count into GetFoo, you're not alone. The syntax is sure a little strange in first sight.

Example:

public (int sum, int count) GetFoo()
{
    return (1, 2);
}
Enter fullscreen mode Exit fullscreen mode

Deconstructing

You can deconstruct a tuple into separate parts. There is various way to achieve the same though.

Example:

// Explicit
(int sum, int count) = GetFoo();

// var
(var s, var c) = GetFoo();

// var shorthand
var (s, c) = GetFoo();

// Existing variables
int sum, count;
(sum, count) = GetFoo();

// Deconstructing objects also works
class Student
{
    public string Name { get; set; }
    public int Age { get; set; }

    public void Deconstruct(out string name, out int age)
    {
        name = Name;
        age = Age;
    }
}

var student = new Student { FirstName = "Peter", Age = 22 };
var (name, age) = person;
Enter fullscreen mode Exit fullscreen mode

Tuple initialization

var student = ("Peter", 22);
Console.WriteLine($"Name: {student.Item1}, Age: {student.Item2}");

// Assign item names
var student = (name: "Peter", age: 22);
Console.WriteLine($"Name: {student.name}, Age: {student.age}");
Enter fullscreen mode Exit fullscreen mode

Local functions

Local functions are functions that are defined inside a method and have access to all local variables in that method. Before C#7 you could declare a Func to achieve this, but that is unnecessarily expensive and it looks quite ugly. The nice thing about local functions is that the compiler transforms it to a regular private static method, so there will be literally no overhead.

Example:

static void Main(string[] args)
{
    int Sum(int x, int y)
    {
        return x + y;
    }

    Console.WriteLine(Sum(10, 20));
    Console.ReadKey();
}
Enter fullscreen mode Exit fullscreen mode

It's worth knowing that local functions support delightful lambda syntax and you can also declare a local function with the same name as an existing private method.

Out variables

The out var declaration is syntax sugar to improve readability when using TryParse.

Example:

Before:

int value;
if (int.TryParse(input, out value)) 
{
    Foo(value);
} 
else 
{
    Foo(value);
}
Foo(value);
Enter fullscreen mode Exit fullscreen mode

Now:

if (int.TryParse(input, out var value)) 
{
    Foo(value);
}
else 
{
    Foo(value);
}
Foo(value); // Value is still in scope
Enter fullscreen mode Exit fullscreen mode

Digit separators

In C#7 we have the underscore _ as digit separators. This is purely syntax sugar but it does improve readability in large numbers.

Example:

int bin = 0b1001_1010_0001_0100;
int num = 1_2__2_3_4_5_6_3; // Separators is simply ignored
Enter fullscreen mode Exit fullscreen mode

Pattern Matching

In C#7 we get pattern matching. No doubt C# is getting a little more functional with every new release.

is

The is operator is used to checking if an object is compatible with a specific type, e.g. if a specified interface is implemented. In C#7 you can use is to check for patterns.

Example:

Before:

string s = o as string;
if(s != null)
{
    // Do something with s
}
Enter fullscreen mode Exit fullscreen mode

Now:

if(o is string s)
{
    // Do something with s
};
Enter fullscreen mode Exit fullscreen mode

switch

The switch statement has been enhanced as well. Using case, you can check for a const pattern (this was possible before), a type pattern to immediately declare a variable of the specified type, and the var pattern.

You could also use the when keyword to enhance the pattern filter to only apply when a specific condition is fulfilled. This is the same keyword already used with exception filters in C#6.

Example:

public static void SwitchPattern(object o)
{
    switch (o)
    {
        case null:
            Console.WriteLine("It's a constant pattern");
            break;
        case int i:
            Console.WriteLine("It's an int");
            break;
        case Person p when p.FirstName.StartsWith("An"):
            Console.WriteLine($"a An person {p.FirstName}");
            break;
        case Person p:
            Console.WriteLine($"Any other person {p.FirstName}");
            break;
        case var x:
            Console.WriteLine($"it's a var pattern with the type {x?.GetType().Name}");
            break;
        default:
            break;
    }
}
Enter fullscreen mode Exit fullscreen mode

Learn more

If you want to dig deeper into the neat new features in C#7, there are quite some material you can read.

Discussion (0)