ReSharper:if / else if vs switch in C#

时间:2013-12-23 10:51:23

标签: c# refactoring resharper

所以我正在与同事讨论ReSharper(目前是v8.1)在重构if / else if语句来转换语句方面的好处。我没有多想过,但我的同事想出了下面的例子。问题在于,当代码运行时,您可以看到它实际上是在DoElseIf中的“else”语句,而不是在DoSwitch中。即便如此,ReSharper建议我将if / else if重构为switch语句,因为显然编译代码的行为方式不同。

任何对ReSharper有更多了解的人都可以告诉我,如果我以错误的方式看待这个问题,或者我是否应该小心将if / else if重构为switch语句?

以下是代码:

namespace ConsoleApplication1
{
   class Program
   {
          static bool MyValue { get; set; }
          static void Main(string[] args)
          {
                 Task t = new Task(ChangeIt);
                 t.Start();

                 for (var i = 0; i < 1000000; i++)
                 {
                       DoElseIf();
                 }
                 for (var i = 0; i < 1000000; i++)
                 {
                       DoSwitch();
                 }

                 Console.WriteLine("Work's done!");
                 Console.ReadLine();
          }

          static void DoSwitch()
          {
                 switch (MyValue)
                 {
                       case true:
                              //Console.WriteLine("true");
                              break;
                       case false:
                              //Console.WriteLine("false");
                              break;
                       default:
                              Console.WriteLine("WTF (Switch)!");
                              break;
                 }
          }

          static void DoElseIf()
          {
                 if (MyValue == true)
                 {
                       //Console.WriteLine("true");
                 }
                 else if (MyValue == false)
                 {
                       //Console.WriteLine("false");
                 }
                 else
                 {
                       Console.WriteLine("WTF (Else-if)!");
                 }
          }

          public static void ChangeIt()
          {
                 MyValue = !MyValue;
                 Task.Factory.StartNew(ChangeIt);
          }
   }
}

感谢所有人提前和节日快乐: - )

3 个答案:

答案 0 :(得分:5)

您的示例是一个非常特殊的情况,您在非线程安全循环中运行if语句,这意味着您期望另一个任务在评估变量时更改变量值。

通常你想要防止这种情况,因为这会导致非常糟糕的问题。

关于你的问题,ReSharper应该如何了解这一事实?通常,如果你执行if / elseif,我们可以期望正确评估语句吗?

此外,该开关甚至可以帮助您防止这种混乱,所以在我看来,R#是对的;)

但是,当然,如果不仔细检查建议,你就不能盲目信任R#。通常一些建议是废话,你还必须配置R#以匹配你的代码风格指南等......它只是一个工具;)

答案 1 :(得分:3)

R#是一个非常有用的工具,可以帮助您编写更好的代码。它的建议永远不会破坏工作代码吗?不,这也是为什么没有“对所有提议的重构都是肯定的”按钮的原因。

回答您的问题更通用:您应该始终了解R#对您的代码所做的更改。你是程序员。

PS:当您发现R#破坏了工作代码的情况时,再看看那段特定的代码,它可能质量很差。

PPS:我已经使用R#很长时间了,并且从未遇到过R#建议实现错误的例子:)

答案 2 :(得分:0)

根据Lasse的评论,这是一个较短的例子:

class Program
{
    private static bool _pathological = true;
    private static bool Pathological
    {
        get
        {
            return (_pathological = !_pathological);
        }
    }

    static void Main(string[] args)
    {
        DoElseIf();
        DoSwitch();

        Console.WriteLine("Work's done!");
        Console.ReadLine();
    }

    static void DoSwitch()
    {
        switch (Pathological)
        {
            case true:
                //Console.WriteLine("true");
                break;
            case false:
                //Console.WriteLine("false");
                break;
            default:
                Console.WriteLine("WTF (Switch)!");
                break;
        }
    }

    static void DoElseIf()
    {
        // R# offers Convert to Switch on the below if, which results
        // in the code in DoSwitch, which has *different* behaviour
        if (Pathological == true)
        {
            //Console.WriteLine("true");
        }
        else if (Pathological == false)
        {
            //Console.WriteLine("false");
        }
        else
        {
            Console.WriteLine("WTF (Else-if)!");
        }
    }
}

我同意这是ReSharper中的一个错误;你应该把它提交给ReSharper bug tracker。 ReSharper错误地假设连续获取属性将返回相同的值。它也错误地为volatile 字段提供转换为开关,这也很糟糕。