所以我正在与同事讨论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);
}
}
}
感谢所有人提前和节日快乐: - )
答案 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
字段提供转换为开关,这也很糟糕。