Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use c# tuple value types in a switch statement

I'm using the new tuple value types in .net 4.7. In this example I am trying to make a switch statement for one or more cases of a tuple:

using System;
namespace ValueTupleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            (char letterA, char letterB) _test = ('A','B');
            Console.WriteLine($"Letter A: '{_test.letterA}', Letter B: '{_test.letterB}'");

            switch (_test)
            {
                case ('A', 'B'):
                    Console.WriteLine("Case ok.");
                    break;
            }

        }
    }
}

This does not compile unfortunately.

How do I take a tuple and make cases in a switch statement correctly?

like image 377
SoftAllan Avatar asked Jun 04 '17 15:06

SoftAllan


People also ask

How is C used?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is || in C programming?

Logical OR operator: || The logical OR operator ( || ) returns the boolean value true if either or both operands is true and returns false otherwise. The operands are implicitly converted to type bool before evaluation, and the result is of type bool .


2 Answers

Answering your question technically, you could use when to check tuple's values:

(char letterA, char letterB) _test = ('A', 'B');
Console.WriteLine($"Letter A: '{_test.letterA}', Letter B: '{_test.letterB}'");

switch (_test)
{
    case var tuple when tuple.letterA == 'A' && tuple.letterB == 'B':
        Console.WriteLine("Case ok.");
        break;
    case var tuple when tuple.letterA == 'D' && tuple.letterB == '\0':
        Console.WriteLine("Case ok.");
        break;
}

However, consider using if version because it may be a more readable and understandable solution.

Another side of this question is single responsibility. Your methods knows what do A and B, D and \0 characters mean which breaks the single-responsibility principle.
In terms of OOP, it is better to separate this knowledge from you main code into a separate method.
Something like that could make code a little cleaner:

private static bool IsCaseOk(char a, char b) 
{
    return (a == 'A' && b == 'B') || (a == 'D' && b == '\0'); // any logic here
}

public static void Main() 
{
    (char letterA, char letterB) _test = ('A', 'B');
    Console.WriteLine($"Letter A: '{_test.letterA}', Letter B: '{_test.letterB}'");

    if (IsCaseOk(_test.letterA, _test.letterB)) {
        Console.WriteLine("Case ok.");
    } else {
        Console.WriteLine("Case not ok.");
    }
}

If these letters have any meaning in your domain, then probably it is a better idea to even create a class with two char properties and encapsulate this logic there.

like image 162
Yeldar Kurmangaliyev Avatar answered Oct 27 '22 18:10

Yeldar Kurmangaliyev


C# 7.3 introduces tuple equality which means your initial idea in the question is almost correct. You just need to capture the value you are comparing like this:

var _test = ('A','B');
switch (_test)
{
   case var t when t == ('A', 'B'):
   Console.WriteLine("Case ok.");
   break;
}
like image 21
Ryan Avatar answered Oct 27 '22 19:10

Ryan