C#7: Underscore ( _ ) & Star ( * ) in Out variable

Solution 1:

Discards, in C#7 can be used wherever a variable is declared, to - as the name suggests - discard the result. So a discard can be used with out variables:

p.GetCoordinates(out var x, out _);

and it can be used to discard an expression result:

_ = 42;

In the example,

p.GetCoordinates(out var x, out _);
_ = 42;

There is no variable, _, being introduced. There are just two cases of a discard being used.

If however, an identifier _ exists in the scope, then discards cannot be used:

var _ = 42;
_ = "hello"; // error - a string cannot explicitly convert from string to int

The exception to this is when a _ variable is used as an out variable. In this case, the compiler ignores the type or var and treats it as a discard:

if (p.GetCoordinates(out double x, out double _))
{
    _ = "hello"; // works fine.
    Console.WriteLine(_); // error: _ doesn't exist in this context.
}

Note that this only occurs if, in this case, out var _ or out double _ is used. Just use out _ and then it's treated as a reference to an existing variable, _, if it's in scope, eg:

string _;
int.TryParse("1", out _); // complains _ is of the wrong type

Finally, the * notation was proposed early in the discussions around discards, but was abandoned in favour of _ due to the latter being a more commonly used notation in other languages.

Solution 2:

Another example of the Discard Operator _ in C# 7 is to pattern match a variable of type object in a switch statement, which was recently added in C# 7:

Code:

static void Main(string[] args)
{
    object x = 6.4; 
    switch (x)
    {
        case string _:
            Console.WriteLine("it is string");
            break;
        case double _:
            Console.WriteLine("it is double");
            break;
        case int _:
            Console.WriteLine("it is int");
            break;
        default:
            Console.WriteLine("it is Unknown type");
            break;
    }

    // end of main method
}

This code will match the type and discard the variable passed to the case ... _.