为什么 Java 和 C# 没有到布尔值的隐式转换?

2022-09-01 13:33:28

自从我开始Java以来,它一直非常恶化,因为它不支持从数字类型到布尔值的隐式转换,所以你不能做这样的事情:

if (flags & 0x80) { ... }

相反,你必须经历这个疯狂:

if ((flags & 0x80) != 0) { ... }

这与 null 和 objects 相同。我所知道的包括JavaScript在内的所有其他类似C的语言都允许它,所以我认为Java只是白痴,但我刚刚发现C#是相同的(至少对于数字,不知道null/objects):http://msdn.microsoft.com/en-us/library/c8f5xwh7(VS.71).aspx

微软故意从C++改变它,那么为什么呢?显然,我错过了一些东西。为什么要改变(我以为是)世界上最自然的东西,让它更长的打字时间?它到底出了什么问题?


答案 1

为清楚起见。它使以下错误完全非法:

int x = ...;

if (x = 0)  // in C: assign 0 to x and always evaluate to false 
   ....     // never executed

注意:大多数现代C / C++编译器都会在这种简单的模式上给出警告(但不是错误),但有很多可能的变化。它可能会悄悄地爬上你。


答案 2

Java 和 C# 都放弃了到布尔值的隐式转换,以减少程序员出错的几率

例如,许多程序员会不小心写:

if( x = 5 ) { ... }

而不是:

if( x == 5 ) { ... }

这当然会导致完全不同的行为,因为第一个语句执行赋值(这将始终导致 true),而第二个语句执行比较。过去,开发人员有时会反向编写此类赋值以避免陷阱,因为:

if( 5 = x ) { ... } // doesn't compile.

现在,在C#中,您仍然可以为自己的类型创建隐式转换运算符 - 尽管很少建议这样做,因为大多数开发人员都不希望这样:bool

public class MyValue
{
   public int Value { get; set; }

   public static implicit operator bool( MyValue mb )
   {
       return mb.Value != 0;
   }
}

MyValue x = new MyValue() { Value = 10; }
if( x ) { ... } // perfectly legal, compiler applies implicit conversion