0

I have the following code snippet in my project (I simplified it as much as possible):

private void someFunc(bool a, bool b, bool c, int x, int y) {
if ((a || b || c) && x != 1)
{
    // do something
} else if ((a || b || c) && y < 0)
{
    // do else
}
}

and IntelliJ Rider IDE offers me to convert to switch statement, which then gives me this:

private void someFunc(bool a, bool b, bool c, int x, int y) {
switch (a)
{
    case true or true or true when x != 1:
        // do something
        break;
    case true or true or true when y < 0:
        // do else
        break;
}
}

What kind of switch syntax is this? What is true or true or true when supposed to mean, it seems super redundant? And most importantly, where did b and c go??

I didn't expect this type of reformatting, and I think it must be a fairly new language feature? I've checked the C# language documentation but didn't find an explanation for a case like this...

6
  • 1
    Well, it could have done better, but it is basically just expanding your constant values in line. Commented Oct 17, 2023 at 10:39
  • 1
    Then try starting from static void M(bool a, bool b, bool c, int x) { if ( ... ) ... } instead. Commented Oct 17, 2023 at 10:41
  • or is just the pattern matching for || Commented Oct 17, 2023 at 10:43
  • 2
    I think it's attempting to do this: case guards Commented Oct 17, 2023 at 10:43
  • 1
    It's clearly a bug in Rider. You should report it to JetBrains. Commented Oct 17, 2023 at 13:01

2 Answers 2

0

The proposed new code does not seem to make sense.


Not in original answer:

The proposed refactoring is not correct. Namely, suppose you start with:

static void M(bool a, bool b, bool c, int x)
{
    if ((a || b || c) && x != 1)
    {
        // do something
    } else if ((a || b || c) && x < 0)
    {
        // do else
    }
}

then (using your values) M(false, false, true, 0) would go into the // do something block, whereas with:

static void M(bool a, bool b, bool c, int x)
{
    switch (a)
    {
        case true or true or true when x != 1:
            // do something
            break;
        case true or true or true when x < 0:
            // do else
            break;
    }
}

the call M(false, false, true, 0) would not enter that block.

I am not addressing the question whether "IntelliJ Rider IDE" actually suggests this change, in the way you say it does.

A better refactoring of your code seems to be:

static void M(bool a, bool b, bool c, int x)
{
    if ((a || b || c) && x != 1)
    {
        // do something
    }
}

where I have removed the // do else part entirely since it could never occur. This is because any number less than 0 would also be unequal to 1.

So as hinted in some comments, your original code probably was not as you intended. However, that is still no excuse for the IDE to suggest a bad refactoring (and again, I am not verifying your claim that it really suggests this).

Sign up to request clarification or add additional context in comments.

3 Comments

@stuartd The question is like "This cannot be a good refactoring, true or true is redundant, and the dependence on b and c was forgotten?". Then the answer should be: "You are correct".
Well, it probably means that the code wasn't so great to begin with... it's a question of how far you want to take the refactoring.
@stuartd Now I expanded it into a long answer instead.
0

due to switch expressions introduced in C# 7, it could be rewirtten as follows

    static async Task Main(string[] args)
    {

        bool a = false, b = true, c = false;
        int x = -5;

        bool d = false;



        string result = (a, b, c) switch
        {
            { } when (a == true || b == true || c == true) && x != 1 && x > 0 => "1",
            { } when (a == true || b == true || c == true) && x < 0 => "2",
            _ => "3"
        };

/////////////////////// OR ////////////////////////

        switch ((a, b, c))
        {
            case { } when (a == true || b == true || c == true) && x != 1 && x > 0:
                // do something
                Console.WriteLine("1");
                break;

            case { } when (a == true || b == true || c == true) && x < 0:
                // do something
                Console.WriteLine("2");
                break;

        }
        Console.ReadLine();
    }

2 Comments

Thanks, but not what I wanted to know
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.