Multi-variable switch statement in C#

You can do this in C# 7 and higher with the when keyword:

switch (intVal1)
{
    case 1 when strVal2 == "hello" && boolVal3 == false:
        break;
    case 2 when strVal2 == "world" && boolVal3 == false:
        break;
    case 2 when strVal2 == "hello" && boolVal3 == false:
        break;
}

There is (was) no built-in functionality to do this in C#, and I don't know of any library to do this.

Here is an alternative approach, using Tuple and extension methods:

using System;

static class CompareTuple {
    public static bool Compare<T1, T2, T3>(this Tuple<T1, T2, T3> value, T1 v1, T2 v2, T3 v3) {
        return value.Item1.Equals(v1) && value.Item2.Equals(v2) && value.Item3.Equals(v3); 
    }
}

class Program {
    static void Main(string[] args) {
        var t = new Tuple<int, int, bool>(1, 2, false);
        if (t.Compare(1, 1, false)) {
            // 1st case
        } else if (t.Compare(1, 2, false)) {
            // 2nd case
        } else { 
            // default
        }
    }
}

This is basically doing nothing more than providing a convenient syntax to check for multiple values - and using multiple ifs instead of a switch.


Yes. It's supported as of .NET 4.7 and C# 8. The syntax is nearly what you mentioned, but with some parenthesis (see tuple patterns).

switch ((intVal1, strVal2, boolVal3))
{
    case (1, "hello", false):
        break;
    case (2, "world", false):
        break;
    case (2, "hello", false):
        break;
}

If you want to switch and return a value there's a switch "expression syntax". Here is an example; note the use of _ for the default case:

string result = (intVal1, strVal2, boolVal3) switch
{
    (1, "hello", false) => "Combination1",
    (2, "world", false) => "Combination2",
    (2, "hello", false) => "Combination3",
    _ => "Default"
};

Here is a more illustrative example (a rock, paper, scissors game) from the MSDN article linked above:

public static string RockPaperScissors(string first, string second)
    => (first, second) switch
    {
        ("rock", "paper") => "rock is covered by paper. Paper wins.",
        ("rock", "scissors") => "rock breaks scissors. Rock wins.",
        ("paper", "rock") => "paper covers rock. Paper wins.",
        ("paper", "scissors") => "paper is cut by scissors. Scissors wins.",
        ("scissors", "rock") => "scissors is broken by rock. Rock wins.",
        ("scissors", "paper") => "scissors cuts paper. Scissors wins.",
        (_, _) => "tie"
    };