C# 中的“else if()”与多个“if()”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14349261/
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 11:32:45  来源:igfitidea点击:

"else if()" versus multiple "if()"s in C#

c#

提问by Jerry Nixon

How do these practically differ?

这些实际上有何不同?

// Approach one
if (x == 1)
    DoSomething();
else if (x == 2)
    DoSomethingElse();

// Approach two
if (x == 1)
    DoSomething();
if (x == 2)
    DoSomethingElse();

Is the resulting CIL the same?

产生的 CIL 是否相同?

(The question Use of “if/elseif/else” versus “if/else{if/else}”exists, but it is yet to be answered.)

使用“if/elseif/else”与“if/else{if/else}”的问题存在,但尚未得到解答。)

采纳答案by Oliver Charlesworth

If DoSomethingsets xto 2, then they will differ.

如果DoSomething设置x为 2,则它们将不同。

回答by Jesus Ramos

If x changes (in Do Seomthing and DoSomethingElse) then the first statement will only ever execute one statement. In the 2nd example every statement will be checked (unless of course the compiler optimizes it to a jump table for number comparison).

如果 x 改变(在 Do Seomthing 和 DoSomethingElse 中),那么第一个语句将只执行一个语句。在第二个示例中,将检查每个语句(当然,除非编译器将其优化为用于数字比较的跳转表)。

回答by JG in SD

If xis modified by multiple threads it is possible that DoSomething()and DoSomethingElse()will both get called with the second approach

如果x是由多个线程修改了它是可能的DoSomething()DoSomethingElse()都将被调用,在第二种方法

回答by horgh

When you use elsestatement, only one of the branches will be run (i.e. the first, which meets the ifcondition). All other ifconditions won't even be estimated:

使用elsestatement 时,只会运行一个分支(即满足if条件的第一个)。if甚至不会估计所有其他条件:

// approach one
int x = 1;
if (x == 1)
    DoSomething(); //only this will be run, even if `DoSomething` changes `x` to 2
else if (x == 2)
    DoSomethingElse();

While when you don't use it each of them may be run (depending on each of the conditions), i.e. each of them is estimated one by one:

而当你不使用它时,它们中的每一个都可以运行(取决于每个条件),即它们中的每一个都被一一估计:

// approach two
int x = 1;
if (x == 1)
    DoSomething();//this is run, as `x` == 1
if (x == 2)
    DoSomethingElse();//if `DoSomething` changes `x` to 2, this is run as well

So, IL may differ.

因此,IL 可能会有所不同。

回答by Gumowy Kaczak

No anwsers about performance?

没有关于性能的答案?

So if x=1 then you do only one check in first case, and in second case you do 2 checks, so first case is faster.

所以如果 x=1 那么你在第一种情况下只做一次检查,在第二种情况下你做 2 次检查,所以第一种情况更快。

回答by Tommaso Belluzzo

[STAThread]
public static void Main()
{
    Int32 x = 1;

    if (x == 1)
        Console.WriteLine("1");
    else if (x == 2)
        Console.WriteLine("2");
}

Results in:

结果是:

.method public hidebysig static void Main() cil managed
{
    .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
    .entrypoint
    .maxstack 2
    .locals init (
        [0] int32 x)
    L_0000: ldc.i4.1 
    L_0001: stloc.0 
    L_0002: ldloc.0 
    L_0003: ldc.i4.1 
    L_0004: bne.un.s L_0011
    L_0006: ldstr "1"
    L_000b: call void [mscorlib]System.Console::WriteLine(string)
    L_0010: ret 
    L_0011: ldloc.0 
    L_0012: ldc.i4.2 
    L_0013: bne.un.s L_001f
    L_0015: ldstr "2"
    L_001a: call void [mscorlib]System.Console::WriteLine(string)
    L_001f: ret 
}

While:

尽管:

[STAThread]
public static void Main()
{
    Int32 x = 1;

    if (x == 1)
        Console.WriteLine("1");

    if (x == 2)
        Console.WriteLine("2");
}

Results in:

结果是:

.method public hidebysig static void Main() cil managed
{
    .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
    .entrypoint
    .maxstack 2
    .locals init (
        [0] int32 x)
    L_0000: ldc.i4.1 
    L_0001: stloc.0 
    L_0002: ldloc.0 
    L_0003: ldc.i4.1 
    L_0004: bne.un.s L_0010
    L_0006: ldstr "1"
    L_000b: call void [mscorlib]System.Console::WriteLine(string)
    L_0010: ldloc.0 
    L_0011: ldc.i4.2 
    L_0012: bne.un.s L_001e
    L_0014: ldstr "2"
    L_0019: call void [mscorlib]System.Console::WriteLine(string)
    L_001e: ret 
}

IL code is a little bit different and here is the main difference:

IL 代码略有不同,主要区别如下:

Approach One: L_0004: bne.un.s L_0011 -> L_0011: ldloc.0 with L_0010: ret 
Approach Two: L_0004: bne.un.s L_0010 -> L_0010: ldloc.0 with no ret in between

When you use else statement, as in first approach, only the first branch that meets the condition will be run. On the other hand... with the second approach every check is processed and every check that meets the condition will be followed and processed. That's the main difference.

当您使用 else 语句时,与第一种方法一样,只会运行满足条件的第一个分支。另一方面......使用第二种方法,每个检查都会被处理,并且每个满足条件的检查都将被跟踪和处理。这是主要的区别。

That's why in the first approach's IL code you have a "ret" directive just after the call of Console.WriteLine while in the second it's not present. In the first case the method can be exited just after a check has been passed because no more checks on xwill be performed... in the second approach you have to follow all of them sequentially and that's why ret is only appearing at the end of the method, no "shortcuts" to the end.

这就是为什么在第一种方法的 IL 代码中,您在调用 Console.WriteLine 之后有一个“ret”指令,而在第二种方法中它不存在。在第一种情况下,该方法可以在检查通过后立即退出,因为不会执行更多检查x……在第二种方法中,您必须按顺序执行所有这些检查,这就是为什么 ret 仅出现在最后方法,没有“捷径”到最后。

For my test i used a Console.WriteLine()call... but it's sure that if DoSomething()involves a value change of xvariable, the difference will be absolutely more important in the code behavior. Let's say that we have x as a private static member (initial value always 1) instead of a local variable and:

对于我的测试,我使用了一个Console.WriteLine()调用......但可以肯定的是,如果DoSomething()涉及x变量的值更改,则差异在代码行为中绝对更重要。假设我们将 x 作为私有静态成员(初始值始终为 1)而不是局部变量,并且:

public void DoSomething()
{
    ++m_X;
}

In the first approach, even if m_Xassumes a value of 2 after DoSomething()is called thanks to the first check, else will make the method exit and DoSomethingElse()will never be called. In the second approach both methods will be called.

在第一种方法中,即使由于第一次检查而m_XDoSomething()调用后假定值为 2 ,否则会使方法退出并且DoSomethingElse()永远不会被调用。在第二种方法中,这两种方法都将被调用。

回答by drum

When you use multiple else if, it will execute the condition that meets. If there are remaining cases, they will be skipped. When you have multiple if, it will check every statement. So this becomes more of a performance issue.

当你使用 multiple 时else if,它会执行满足的条件。如果还有剩余案例,它们将被跳过。当您有多个时if,它会检查每个语句。所以这更像是一个性能问题。

回答by Bojan Resnik

Note that there is no else ifconstruct in C#. Your first code sample is exactly the same as:

请注意,else ifC# 中没有构造。您的第一个代码示例与以下内容完全相同:

if (x == 1)
    DoSomething();
else 
{
    if (x == 2)
        DoSomethingElse();
}

Since there is only one statement in else, the braces can be omitted, and for enhanced readability, ifis usually written on the same line as the preceding else. Writing multiple "else if" statements is equivalent to further nesting:

由于 中只有一条语句else,大括号可以省略,为了增强可读性,if通常与前面的 写在同一行else。编写多个 " else if" 语句相当于进一步嵌套:

if (x == 1)
    DoSomething();
else 
{
    if (x == 2)
        DoSomethingElse();
    else
    {
        if (x == 3)
            YetSomethingElse();
        else
        {
            if (x == 4)
               ReallyDifferent();
        }
    }
}

The above can be written as:

上面的可以写成:

if (x == 1)
    DoSomething();
else if (x == 2)
    DoSomethingElse();
else if (x == 3)
    YetSomethingElse();
else if (x == 4)
    ReallyDifferent();

From this, you can see that chaining "else if" and ifcan produce different results. In case of "else if", the first branch that satisfies the condition will be executed, and after that no further checks are done. In case of chained ifstatements, all branches that satisfy their conditions are executed.

由此可以看出,链接“ else if”并if可以产生不同的结果。在“ else if”的情况下,第一个满足条件的分支将被执行,之后不再进行进一步的检查。在链式if语句的情况下,所有满足其条件的分支都会被执行。

The main difference here is when execution of a branch causes a subsequent condition to become true. For example:

这里的主要区别是分支的执行何时导致后续条件变为真。例如:

   var x = 1;

   if (x == 1)
       x = 2;
   else if (x == 2)
       x = 3;

VS

VS

   var x = 1;

   if (x == 1)
       x = 2;

   if (x == 2)
       x = 3;

In the first case, x == 2, while in the second case x == 3.

在第一种情况下,x == 2,而在第二种情况下x == 3

回答by Ravi Kiran

When you code like this

当你这样编码时

// approach two
if (x == 1)
    DoSomething();
if (x == 2)
    DoSomethingElse();

Everytime the condition checks.

每次条件检查。

But when you code like this

但是当你这样编码时

if (x == 1)
    DoSomething();
else if (x == 2)
    DoSomethingElse();

If the first condition is true then it wont check next else if condition and thus decrease unnecessary compiling.

如果第一个条件为真,则它不会检查下一个 else if 条件,从而减少不必要的编译

回答by Don't Know

Else if will only be evaluated if the first condition wasn't true. But two consecutive if statements will both be evaluated.

否则 if 只会在第一个条件不成立时进行评估。但是两个连续的 if 语句都将被评估。

You can easily test this concept in a Python interpreter:

您可以在Python 解释器中轻松测试此概念:

First run this:

首先运行这个:

Note: In Python elif is used instead of else if

注意:在 Python 中使用 elif 而不是 else if

a = 1
if a >= 1:
  print('a is greater than or equal to 1')
elif a<=1:
  print('a is less than or equal to 1')

then run this

然后运行这个

a=1
if a >= 1:
  print('a is greater than or equal to 1')
if a<=1:
  print('a is less than or equal to 1')