C# 如果开关盒内的条件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15742610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 17:48:44  来源:igfitidea点击:

If Condition inside switch case

c#if-statementswitch-statement

提问by AngelicCore

I am trying to convert an if statement to switch cases (for readability)

我正在尝试将 if 语句转换为 switch case(为了可读性)

1) I've read switch statements are aweful in general - Is that true? https://stackoverflow.com/questions/6097513/switch-statement-inside-a-switch-statement-c

1) 我读过 switch 语句一般都很棒 - 这是真的吗? https://stackoverflow.com/questions/6097513/switch-statement-inside-a-switch-statement-c

2) The statement goes like this:

2)语句是这样的:

switch (Show)
                {
                    case Display.Expense:
                        if (expected.EXPENSE != true)
                            break;
                    case Display.NonExpense:
                        if (expected.EXPENSE == true)
                            break;
                    case Display.All:
                        //Code
                        break;
                }

Error is:

错误是:

Control cannot fall through from one case label ('case 1:') to another

控制不能从一个 case 标签('case 1:')落到另一个

This is the original if statement:

这是原始的 if 语句:

if ((Show == Display.All) || (expected.EXPENSE == true && Show == Display.Expense) || (expected.EXPENSE == false && Show == Display.NonExpense))
{
    //Code
}

采纳答案by Lasse V. Karlsen

The compiler will not understand what you mean here.

编译器不会理解你在这里的意思。

switch (Show)
{
    case Display.Expense:
        if (expected.EXPENSE != true)
            break;
        // missing break here
    case Display.NonExpense:

The compiler will not connect the dots and understand that the break;statement inside your ifstatement is linked to the switchstatement. Instead it will try to link it to a loop, since break;statements on their own can only be used with loops, to break out of it.

编译器不会连接点并理解break;您的if语句中的语句与该switch语句相关联。相反,它会尝试将它链接到一个循环,因为break;它们自己的语句只能与循环一起使用,以打破它。

That means that your caseblock is missing its breakstatement to complete it, and thus the compiler complains.

这意味着您的case块缺少break完成它的语句,因此编译器会抱怨。

Instead of trying to wring the necessary code out of a switchstatement, I would instead break up your original ifstatement.

我不会试图从switch语句中挤出必要的代码,而是分解您的原始if语句。

This is yours:

这是你的:

if ((Show == Display.All) || (expected.EXPENSE == true && Show == Display.Expense) || (expected.EXPENSE == false && Show == Display.NonExpense))
{
    //Code
}

This is how I would write it:

我会这样写:

bool doDisplayExpected =
       (Show == Display.All)
    ||?(Show == Display.Expense    && expected.EXPENSE)
    ||?(Show == Display.NonExpense && !expected.EXPENSE);
if (doDisplayExpected)
{
    // code
}

You don't haveto pack everything on one line.

您不必将所有内容打包在一条线上。

Also, I would try to name properties so that they're easier to read, I would rename the EXPENSEproperty to IsExpenseso that the above code would read like this:

此外,我会尝试命名属性,以便它们更易于阅读,我会将EXPENSE属性重命名为,IsExpense以便上面的代码如下所示:

bool doDisplayExpected =
       (Show == Display.All)
    ||?(Show == Display.Expense    && expected.IsExpense)
    ||?(Show == Display.NonExpense && !expected.IsExpense);
if (doDisplayExpected)
{
    // code
}

Then, ideally, I would refactor out the sub-expressions to methods:

然后,理想情况下,我会将子表达式重构为方法:

bool doDisplayExpected =
       ShowAll()
    ||?ShowExpense(expected)
    ||?ShowNonExpense(expected);
if (doDisplayExpected)
{
    // code
}

public bool ShowAll()
{
    return Show == Display.All;
}

public bool ShowExpense(Expected expected)
{
    return Show == Display.Expense && expected.EXPENSE;
}

public bool ShowNonExpense(Expected expected)
{
    return Show == Display.NonExpense && !expected.EXPENSE;
}

Then you can put the expression back into the if-statement:

然后你可以把表达式放回 if 语句中:

if (ShowAll() ||?ShowExpense(expected) ||?ShowNonExpense(expected))
{
    // code
}

This should be easier to read, and change later on.

这应该更容易阅读,并在以后更改。

回答by Hossein Narimani Rad

Provide the elsepart for each of them so it will not throw error, however as others say, you actually don't need switchin this case.

else他们每个人提供一部分,这样它就不会抛出错误,但是正如其他人所说,switch在这种情况下你实际上不需要。

switch (Show)
{
    case Display.Expense:
         if (expected.EXPENSE != true)
             // do what you want
             break;
         else 
             // do what you want
             break;
    case Display.NonExpense:
         if (expected.EXPENSE == true)
             // do what you want
             break;
         else 
             // do what you want
             break;
    case Display.All:
        //Code
        break;
}

回答by Dennis

If you want readability, just throw away your syntax trash:

如果你想要可读性,只需扔掉你的语法垃圾:

if (Show == Display.All || expected.EXPENSE && Show == Display.Expense || !expected.EXPENSE && Show == Display.NonExpense)
{
    //Code
}

回答by illegal-immigrant

Use if statements and extract complex conditions into methods, e.g

使用 if 语句并将复杂的条件提取到方法中,例如

if (ShowAll() || ShowExpense())
{
}

Remember about OOP and polymorphism every time you write such 'switch', adding another case to that code will be a nightmare

每次编写这样的“开关”时都要记住 OOP 和多态性,向该代码添加另一个案例将是一场噩梦

see thisand similar (C++)instructions about converting switches

请参阅有关转换开关的类似(C++)说明

P.Sif you are interested in making your code clean and readable, consider reading Smalltalk Best Practice Patterns by Kent Beckand/or Clean Code by Uncle BobI really enjoyed both of them, highly recommend.

PS如果您有兴趣使您的代码简洁易读,请考虑阅读Kent Beck 的 Smalltalk Best Practice Patterns和/或Uncle Bob 的 Clean Code我真的很喜欢这两本书,强烈推荐。

回答by Matthew Watson

Refactor out the ifstatements so you can express it like so:

重构if语句,以便您可以这样表达:

if (isDisplayAll() || isExpense(expected) || isNonExpense(expected))
{
    // Code
}

The extracted logic:

提取的逻辑:

private bool isDisplayAll()
{
    return (Show == Display.All);
}

private bool IsExpense(Expected expected)
{
    return expected.EXPENSE && (Show == Display.Expense);
}


private bool IsNonExpense(Expected expected)
{
    return !expected.EXPENSE && (Show == Display.NonExpense);
}

回答by bas

The reason why you get this error is that you are not defining breakstatements.

出现此错误的原因是您没有定义break语句。

You defined the breakconditionally.

break有条件地定义了。

            switch (Show)
            {
                case Display.Expense:
                    if (expected.EXPENSE != true)
                        break;

                // Note that the break above is in scope of you if statement, and will
                // result in a compiler error
                case Display.NonExpense:
                    ...
            }

Either make sure every case statement has its own breakor group the case statements as follows.

要么确保每个 case 语句都有自己的语句,要么将 case 语句break分组如下。

            switch (Show)
            {
                case Display.Expense:
                case Display.All:
                    // do stuff
                    // Expense and All have the same behavior
            }

回答by publicgk

Agree with Dennis, you don't want a switch case for this problem.

同意丹尼斯的观点,你不想要一个开关盒来解决这个问题。

Although probably less readable, you can also use shorter:

虽然可能不太可读,但您也可以使用更短的:

if (Show == Display.All || (expected.EXPENSE == (Show == Display.Expense)))
{
    //Code
}

回答by Eric Lippert

First off, I notice that you forgot to ask a question in your second point. So I'm going to ask some questions for you addressing your second point:

首先,我注意到您在第二点忘记提出问题。所以我要问你一些问题来解决你的第二点:

What is the meaning of the "can't fall through" error?

“无法通过”错误是什么意思?

Unlike C and C++, C# does not allow accidental fall-through from one switch section to another. Every switch section must have an "unreachable end point"; it should end with a break, goto, return, throw or (rarely) infinite loop.

与 C 和 C++ 不同,C# 不允许从一个开关部分意外跌落到另一部分。每个开关段都必须有一个“无法到达的端点”;它应该以中断、转到、返回、抛出或(很少)无限循环结束。

This prevents the common bug of forgetting to put in the break and "falling through" accidentally.

这可以防止常见的错误,即忘记放入中断并意外“掉线”。

You've written your code as though fall-through is legal; my guess is that you're a C programmer.

您已经编写了代码,就好像失败是合法的一样;我猜你是 C 程序员。

How can I force fall-through in C#?

如何在 C# 中强制执行失败?

Like this:

像这样:

switch (Show)
{
case Display.Expense:
    if (expected.EXPENSE != true)
        break;
    else
        goto case Display.All;
case Display.NonExpense:
    if (expected.EXPENSE == true)
        break;
    else  
        goto case Display.All;
case Display.All:
    //Code
    break;
}

Now the reachability analyzer can determine that no matter which branch of the "if" is taken, the switch section endpoint is unreachable.

现在可达性分析器可以确定无论采取“if”的哪个分支,切换段端点都是不可达的。

Is this good style?

这是好风格吗?

No. Your original code was a lot more readable.

不。您的原始代码可读性更高。

I've read switch statements are aweful in general - Is that true?

我读过 switch 语句一般都很棒 - 这是真的吗?

Opinions vary. Switch statements are very useful when there is a small number of very "crisp" alternatives whose behaviours do not interact in complex ways. Some people will tell you that switched logic should instead be handled by virtual methods or visitor patterns, but that can be abused as well.

意见不一。当有少量非常“清晰”的替代品,它们的行为不会以复杂的方式交互时,switch 语句非常有用。有些人会告诉您切换逻辑应该由虚拟方法或访问者模式处理,但这也可能被滥用。

Should I use a switch in this particular case?

在这种特殊情况下我应该使用开关吗?

I wouldn't.

我不会。

How would you improve my code?

你会如何改进我的代码?

if ((Show == Display.All) || 
    (expected.EXPENSE == true && Show == Display.Expense) || 
    (expected.EXPENSE == false && Show == Display.NonExpense))
{
    //Code
}

First off, don't name things IN ALL CAPS in C#.

首先,不要在 C# 中全部大写。

Second, don't compare Booleans to true and false. They're already Booleans! If you want to know the truth of statement X you would not say in English "is it true that X is true?" You would say "Is X true?"

其次,不要将布尔值与真假进行比较。他们已经是布尔人了!如果你想知道陈述 X 的真假,你不会用英语说“X 是真的吗?” 你会说“X 是真的吗?”

I would likely write:

我可能会写:

if (Show == Display.All || 
    Show == Display.Expense && expected.Expense || 
    Show == Display.NonExpense && !expected.Expense)
{
    //Code
}

Or, even better, I would abstract the test away into a method of its own:

或者,更好的是,我会将测试抽象为一种自己的方法:

if (canDisplayExpenses())
{ 
    //Code
}

Or abstract the whole thing away:

或者把整个事情抽象出来:

DisplayExpenses();