C# 7.0 type pattern matching usage without variable

1.1k views Asked by At

Assuming that I have Base and Child1, Child2, Child3 classes, I have the following code:

Base b; // value is acquired
switch (b) 
{
    case Child1 child1:
        ProcessChild1(child1);
        break;

    case Child2 child2:
    case Child3 child3:
        ProcessAnyOther(b); // <--
        break;

    default:
        throw new ArgumentOutOfRangeException(nameof(b));
}

Note that at the commented line I don't need these child2, child3 variables since it doesn't matter what type it has, if it is not child1.
Resharper suggests me that unused variable can be safely removed. Here comes the interesting part.

  1. I cannot do that:

    case Child2:
    case Child3:
    

    since it results into "class name is not valid at this point" syntax error.
    This usage seems the most appropriate for me.

  2. I cannot do that:

    case Child2 nevermind:
    case Child3 nevermind:
    

    since it results into "conflicting variable" error. By the way, this statement would make sense if ProcessAnyOther method accepted more precise type (base for Child2 and Child3) and I called it with nevermind argument instead of b.

  3. However, I can do that:

    case Child2 _:
    case Child3 _:
    

    And it does not even create "_" variable. That's exactly what Resharper suggests to do.

My question is: what is this? Where else can it be used? How is this "_" operator or language part called? Is it a part of C# language specification?

1

There are 1 answers

0
René Vogt On BEST ANSWER

It's called a discard and yes it is part of the C#7 specification.

From the linked article:

Discards are local variables which you can assign but cannot read from. i.e. they are “write-only” local variables. They don’t have names, instead, they are represented as a _ is a contextual keyword, it is very similar to var, and _ cannot be read (i.e. cannot appear on the right side of an assignment.)

By naming the variable _ you tell the compiler that you will never access this variable again, so it can ignore the problems you have in your first two versions.