Skip to content

7.0

C# 7.0, released with Visual Studio 2017 and .NET Framework 4.7, introduced several new features aimed at improving code clarity and reducing common coding patterns' complexity. Here are some of the key features introduced in C# 7.0, along with examples and comparisons to earlier versions of C#:

1. Tuples and Deconstruction

C# 7.0 introduced built-in support for tuples, allowing you to return multiple values from a method without creating a custom class or struct. It also introduced deconstruction, enabling you to decompose a tuple into separate variables.

C# 7.0

public (string, int) GetNameAndAge() => ("Alice", 30);

var (name, age) = GetNameAndAge();
Console.WriteLine($"Name: {name}, Age: {age}");

C# < 7.0 Before C# 7.0, you would typically use out parameters or define a custom class or struct to return multiple values from a method.

public void GetNameAndAge(out string name, out int age)
{
    name = "Alice";
    age = 30;
}

string name;
int age;
GetNameAndAge(out name, out age);
Console.WriteLine($"Name: {name}, Age: {age}");

2. Pattern Matching

Pattern matching in C# 7.0 introduced more expressive ways to handle type checking and casting, particularly useful within switch statements or is expressions.

C# 7.0

object obj = 42;
if (obj is int number)
{
    Console.WriteLine($"Integer: {number}");
}

C# < 7.0 Previously, type checking and casting were more verbose and less intuitive.

object obj = 42;
if (obj is int)
{
    int number = (int)obj;
    Console.WriteLine($"Integer: {number}");
}

3. Local Functions

C# 7.0 allows you to define functions within the scope of another method, enhancing encapsulation and readability for helper functions that are only relevant within a single method.

C# 7.0

public int Add(int x, int y)
{
    return AddInternal(x, y);

    int AddInternal(int a, int b) => a + b;
}

C# < 7.0 In earlier versions, you would typically use private methods or lambda expressions for similar functionality, which could clutter the class's API or be less efficient.

public int Add(int x, int y)
{
    Func<int, int, int> addInternal = (a, b) => a + b;
    return addInternal(x, y);
}

4. Out Variables

C# 7.0 introduced the ability to declare out variables inline, simplifying methods that return values via out parameters.

C# 7.0

if (int.TryParse("123", out int result))
{
    Console.WriteLine(result);  // Output: 123
}

C# < 7.0 Previously, you needed to declare out variables before the method call.

int result;
if (int.TryParse("123", out result))
{
    Console.WriteLine(result);
}

5. Ref Returns and Locals

C# 7.0 introduced ref returns and locals, allowing methods to return references to variables, rather than values, which can improve performance for certain scenarios.

C# 7.0

public ref int Find(int[] numbers, int target)
{
    for (int i = 0; i < numbers.Length; i++)
    {
        if (numbers[i] == target)
        {
            return ref numbers[i];  // Return a reference to the found element
        }
    }
    throw new IndexOutOfRangeException("Not found");
}

int[] array = { 1, 2, 3 };
ref int refToTwo = ref Find(array, 2);
refToTwo = 4;  // Updates the array element directly
Console.WriteLine(array[1]);  // Output: 4

C# < 7.0 Before C# 7.0, methods could only return values, not references. Changing a value in an array or a large structure required returning the entire updated structure or modifying it via an out or ref parameter.