我刚刚在一些Exchange 2010代码中看到了这段代码,我想知道是否有人知道程序员为什么这样做了。我从未见过像这样格式化的If语句。看起来如此倒退必定有一个很好的理由吗?
if (true == MsgItem.HasAttachments)
{
// Code
}
我假设它可能会对编码相同内容的各种其他方式进行一些优化;
if (MsgItem.HasAttachments)
{
// Code
}
或
if (MsgItem.HasAttachments == true)
{
// Code
}
这不是什么大问题,我只是好奇。
谢谢, 麦克
更新:感谢所有有趣的观点。摘要似乎归结为传统编码标准。
答案 0 :(得分:31)
这是C或C ++的遗留习惯,你可能不小心做了:
if (i = 1) {
}
这意外地将1
分配给i
而不是进行比较。
撤销支票中的顺序可以防止出现这种常见错误。
if (1 = i) {
}
这将无法编译,很容易看到您错误地输入=
而不是==
。
这仍然与C#中的bools
相关,因为赋值的值是指定的值。
为此:
if (SomeBoolVar = true) {
}
永远都是如此,因为您将true
存储到评估为SomeBoolVar
的{{1}}中。一个可能难以追查的小错误。
答案 1 :(得分:14)
C ++和C程序员有时会先将常量放在第一位,以免意外写入
if (variable = constant)
将执行任务。
特别是,显式地用于布尔比较,假设HasAttachments
是可写的,这个语句将编译并运行而没有警告 1 ,但在C#中没有预期的行为:
if (MsgItem.HasAttachments = true)
对于非布尔表达式,这通常不是C#中的问题,因为if
语句的条件必须可隐式转换为bool
...而对于布尔表达式,您的中间无论如何,表格是首选:
if (MsgItem.HasAttachments)
如果它完全具有任何性能影响,我会感到惊讶 - 并且可能对生成的IL没有任何影响。
1 糟糕 - MS C#编译器确实警告过:
警告CS0665:条件表达式中的赋值始终是常量;你的意思是使用==而不是=?
我没有在Mono下试过它;可能会也可能不会发出警告。它当然是有效的 C#代码。
答案 2 :(得分:11)
这些被称为“Yoda Conditions” - 最初的想法是,如果您不小心键入单个=
,编译将失败,因为常量值位于左侧。
答案 3 :(得分:6)
因为程序员是一个小丑:-)布尔条件的全部意义在于你将它们命名为使得 sense 为布尔值:
if (MsgItem.HasAttachments)
这显然是这样的,我不知道为什么编码员通过测试对true
的平等来自责。
因为,严肃地说,true == MsgItem.HasAttachments
只是另一个布尔值,所以你在哪里停止?
if (true == MsgItem.HasAttachments)
if (true == (true == MsgItem.HasAttachments))
if (true == (true == (true == MsgItem.HasAttachments)))
: : :
依此类推,无限无休。
首先使用常量来避免意外使用=
赋值而不是==
相等的问题应该不是问题,因为你不应该检查一个布尔值true
或false
。你应该使用以下之一:
if (cond)
if (!cond)
答案 4 :(得分:3)
写if (true == myvar)
有一个很好的理由:变量(或表达式)可能不是布尔表达式 - 它可能是bool?
。那么表达式将等同于if(myvar ?? false)
- 我更喜欢第二种语法,因为很明显你正在处理一个可以为空的值。技术上可能正在使用自定义==
运算符(可能与隐式类型转换相结合),但这样做的可能性很小,因为这样做通常不赞成,也不实用或不方便。
正如许多其他人所指出的那样,放置常数可以减少意外错误 - 就个人而言,我认为这些错误不会经常发生,但它不会造成伤害。
然而,最有可能的是,原作者在编写该代码时只是有点困惑。
答案 5 :(得分:2)
在mono下,它们都生成相同的IL(ldloc.0; brfalse <LOC>
):
来源:
using System;
class Foo
{
static void Main()
{
bool bar = Console.ReadLine() == "bar";
if (bar)
{
Console.WriteLine("bar");
}
if (true == bar)
{
Console.WriteLine("true == bar");
}
if (bar == true)
{
Console.WriteLine("bar == true");
}
}
}
IL:
// snip...
IL_000a: call bool string::op_Equality(string, string)
IL_000f: stloc.0
IL_0010: ldloc.0
IL_0011: brfalse IL_0020
IL_0016: ldstr "bar"
IL_001b: call void class [mscorlib]System.Console::WriteLine(string)
IL_0020: ldloc.0
IL_0021: brfalse IL_0030
IL_0026: ldstr "true == bar"
IL_002b: call void class [mscorlib]System.Console::WriteLine(string)
IL_0030: ldloc.0
IL_0031: brfalse IL_0040
// snip...
就个人而言,当人们if (SomePredicate() == true)
时,它会让我感到疯狂。除非它实际上返回一个带有重载==
运算符的对象,否则完全不需要与true
进行比较。为什么停止比较?
// make extra sure SomePredicate returns true
if ((SomePredicate() == true) == true)
{
// ...
}
答案 6 :(得分:1)
可能==
运算符已超载且MsgItem.HasAttachments
有更多信息,只有bool
?我不知道。只是一个想法。
答案 7 :(得分:0)
这是编写关键任务代码时的常见要求。当您打算进行检查时,它可以防止意外分配。在像C#这样的语言中,编译器会警告你它,所以它不是必要的,但对许多程序员来说这是一个遗留下来的习惯。