New C# 7.0 features in Visual Studio 15 Preview release

Introduction

A number of new C# 7.0 features were introduced with the Visual Studio 15 preview release on August 24, 2016. These features are showcased in this centralized VS 15 preview sample solution. 

This sample demonstrates 7 new C# 7.0 features:

 • Out variables

 • Pattern matching

 • Tuples

 • Deconstruction

 • Local functions

 • Digit separator

 • Ref returns and locals

Sample prerequisites

This sample solution needs Visual Studio 15 to run. Download the latest Visual Studio 15 preview to begin.

Running the sample

• Open Visual Studio 15, click File > Open > Project/Solution in menu, and then, find the file “CS70Sample.sln” and double-click on it to open this Solution.



• Right-click Solution ‘CS70Sample’ in Solution Explorer, and then click “Restore NuGet Packages



• Then choose a branch of this sample you interested to read or debug it as you wish.

Using the code

Out variables

C# 7.0 has the ability to declare an out variable at the point which it is passed as an out argument.

C#
Edit|Remove
class OutVariablesSample 
{ 
    public static void Run() 
    { 
        // declare out variables in function call, and use those variables in the same scope 
        if (GetXY(out int i, out int j)) { 
            Console.WriteLine($"x: {i}, y: {j}"); 
        } 
    } 
 
    static bool GetXY(out int x, out int y) 
    { 
        x = 0; 
        y = 1; 
        return true; 
    } 
} 
Pattern matching

C# 7.0 introduces “pattern matching” abstract to determine the value for “Type, value” and then extract it if the test passes.

In the sample, we will demonstrate 3 different kinds of patterns

 • Type pattern

 • Determine the type of the value and then assign the value to the new type identifier if the test passes.

 • Constant pattern

 • Determine the value and test whether it is equal to the value to be tested.

 • var pattern

 • Create a new identifier and assign the original value to it.

 

There are 2 approaches to apply the patterns listed above:

 • Is expression

C#
Edit|Remove
static void IsExpressionWithPattern() 
{ 
    var content = "Hello pattern"; 
 
    // 1. type pattern 
    if (content is string str) { 
        Console.WriteLine($"Is expression with type pattern, value is \"{str}\""); 
    } 
    // 2. constant pattern 
    if (content is "Hello pattern") { 
        Console.WriteLine($"Is expression with constant pattern, constant check successfully"); 
    } 
    // 3. var pattern 
    if (content is var j) { 
        Console.WriteLine($"Is expression with var pattern, variable identifier change to \"j\" and value is \"{j}\""); 
    } 
} 
 

• Switch statement

 

C#
Edit|Remove
static void SwitchStatementsWithPattern() 
{ 
    var content = "Hello pattern"; 
 
    // 1. type pattern 
    switch (content) { 
        case string str: { 
                Console.WriteLine($"Switch expression with type pattern, value is \"{str}\""); 
                break; 
            } 
        case null: { 
                break; 
            } 
    } 
    // 2. constant pattern 
    switch (content) { 
        case "Hello pattern": { 
                Console.WriteLine($"Switch expression with constant pattern, constant check successfully"); 
                break; 
            } 
        case null: { 
                break; 
            } 
    } 
    // 3. var pattern 
    switch (content) { 
        case var j: { 
                Console.WriteLine($"Switch expression with var pattern, variable identifier change to \"j\" and value is \"{j}\""); 
                break; 
            } 
    } 
} 

Tuples

C# 7.0 provides an easy solution to returning the tuple from a function instead of using the long template tuple class type.

C#
Edit|Remove
static (string FirstName, string MiddleName, string LastName) SplitFullName(string fullName) 
{ 
    var names = fullName.Split(' ''\t'); 
    switch(names.Length) { 
        case 2: { 
                return (FirstName: names[0], MiddleName: string.Empty, LastName: names[1]); 
            } 
        case 3: { 
                return (FirstName: names[0], MiddleName: names[1], LastName: names[2]); 
            } 
        default: { 
                return (FirstName: fullName, MiddleName: string.Empty, LastName: string.Empty); 
            } 
    } 
} 

Note: Currently the tuple feature depends on the “System.ValueTuple” package. You can search for it on nuget.org by checking the “Include prerelease” option. 

Deconstruction

C# 7.0 can split the tuple value into individual variables

 

C#
Edit|Remove
// deconstruct for function tuple return value 
(string a, string b, string c) = SplitFullName("Black Big Smith"); 
Console.WriteLine($"Deconstruct on \"SplitFullName\" return value is a: {a}, b: {b}, c: {c}"); 
 
/// <summary> 
///  
/// </summary> 
/// <param name="fullName"></param> 
/// <returns>Return value is named tuple</returns> 
static (string FirstName, string MiddleName, string LastName) SplitFullName(string fullName) 
{ 
    var names = fullName.Split(' ''\t'); 
    switch (names.Length) { 
        case 2: { 
                return (FirstName: names[0], MiddleName: string.Empty, LastName: names[1]); 
            } 
        case 3: { 
                return (FirstName: names[0], MiddleName: names[1], LastName: names[2]); 
            } 
        default: { 
                return (FirstName: fullName, MiddleName: string.Empty, LastName: string.Empty); 
            } 
    } 
} 
You can also deconstruct a class instance if the class has an instant method or an extension method in the form:
C#
Edit|Remove
public void Deconstruct(out T1 x1, out T2 x2, .., out Tn   xn) 
{ 
 … 
}
 
 
C#
Edit|Remove
// deconstruct for class 
var point = new My3DPoint(235); 
(int x, int y, int z) = point; 
Console.WriteLine($"Deconstruct on \"My3DPoint\" instance. x: {x}, y: {y}, z: {z}"); 
 
class My3DPoint 
{ 
    public int X { getset; } 
    public int Y { getset; } 
    public int Z { getset; } 
 
    public My3DPoint(int x, int y, int z) 
    { 
        X = x; 
        Y = y; 
        Z = z; 
    } 
 
    /// <summary> 
    /// Only class declaring "Deconstruct" method will support deconstruct 
    /// </summary> 
    /// <param name="x"></param> 
    /// <param name="y"></param> 
    /// <param name="z"></param> 
    public void Deconstruct(out int x, out int y, out int z) 
    { 
        x = X; 
        y = Y; 
        z = Z; 
    } 
} 
Local functions

Now you can define a function inside  the function like javascript

 

C#
Edit|Remove
class LocalFunctionsSample 
{ 
    public static void Run() 
    { 
        void print(string content) 
        { 
            Console.WriteLine($"Call the local function to print \"{content}\""); 
        } 
 
        print("Hello Local Function"); 
    } 
} 
Digit separator

C# 7.0 allows _ as a digit separator, it makes the code clearer if the number is too long to read

 

C#
Edit|Remove
class DigitSeperatorSample 
{ 
    public static void Run() 
    { 
        // integer 
        int i = 1000; 
        int seperatedInteger = 1_000; 
        Console.WriteLine($"Seperate integer: {i == seperatedInteger}"); 
 
        // float 
        float f = 1.234f; 
        float seperatedFloat = 1.2_34f; 
        Console.WriteLine($"Seperate float: {f == seperatedFloat}"); 
 
        // hex 
        var x = 0xFF00AA; 
        var seperatedX = 0xFF_00_AA; 
        Console.WriteLine($"Seperate hex: {x == seperatedX}"); 
 
        // binary 
        var b = 0b100010100001; 
        var seperatedB = 0b1000_1010_0001; 
        Console.WriteLine($"Seperate binary: {b == seperatedB}"); 
    } 
} 
Ref returns and locals

C# 7.0 can now return a ref type value.

 

C#
Edit|Remove
// the return value is ref type 
static ref int Search(int targetNumber, int[] array) 
{ 
    for (int i = 0; i < array.Length; ++i) { 
        if (array[i] == targetNumber) 
            return ref array[i]; 
    } 
    throw new Exception("Not found"); 
} 
More information

 

• VS 15 download: https://www.visualstudio.com/en-us/downloads/visual-studio-next-downloads-vs.aspx

• C# 7.0 first-hand look: https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/

Microsoft All-In-One Code Framework is a free, centralized code sample library driven by developers' real-world pains and needs. The goal is to provide customer-driven code samples for all Microsoft development technologies, and reduce developers' efforts in solving typical programming tasks. Our team listens to developers’ pains in the MSDN forums, social media and various DEV communities. We write code samples based on developers’ frequently asked programming tasks, and allow developers to download them with a short sample publishing cycle. Additionally, we offer a free code sample request service. It is a proactive way for our developer community to obtain code samples directly from Microsoft.