运算符“>”不能应用于’ulong’和’int’类型

我很想知道为什么C#编译器只给我第二个if语句的错误信息。

enum Permissions : ulong { ViewListItems = 1L, } public void Method() { int mask = 138612833; int compare = 32; if (mask > 0 & (ulong)Permissions.ViewListItems > 32) { //Works } if (mask > 0 & (ulong)Permissions.ViewListItems > compare) { //Operator '>' cannot be applied to operands of type 'ulong' and 'int' } } 

我一直在试验这个,使用ILSpy检查输出,这就是我发现的。

显然在你的第二种情况下这是一个错误 – 你无法比较ulongint因为没有你可以强制转换的类型。 ulong可能太长了,而int可能是负数。

但是,在第一种情况下,编译器很聪明。 它意识到const 1 > const 32永远不会成立,并且根本不包括编译输出中的if语句。 (它应该对无法访问的代码发出警告。)如果你定义并使用const int而不是文字,或者即使你明确地转换文字(即(int)32 ),它也是一样的。

但是, 编译器是否成功地将ulongint进行比较,我们刚才说这是不可能的?

显然不是。 那怎么回事?

请尝试沿着以下方向做一些事情。 (输入和写入输出,因此编译器不会编译任何东西。)

 const int thirtytwo = 32; static void Main(string[] args) { ulong x = ulong.Parse(Console.ReadLine()); bool gt = x > thirtytwo; Console.WriteLine(gt); } 

这将编译,即使ulong是一个变量,即使结果在编译时是未知的。 看看ILSpy中的输出:

 private static void Main(string[] args) { ulong x = ulong.Parse(Console.ReadLine()); bool gt = x > 32uL; /* Oh look, a ulong. */ Console.WriteLine(gt); } 

所以,编译器实际上将你的const int视为ulong 。 如果你使三thirtytwo = -1 ,代码无法编译,即使我们知道gt永远为真。 编译器本身无法将ulongint进行比较。

另请注意,如果将x设为long而不是ulong ,则编译器会生成32L而不是32作为整数,即使它不需要。 (您可以在运行时比较intlong 。)

这指向编译器在第一种情况下不将32视为ulong ,因为它必须 ,因为它可以匹配x的类型。 它可以节省运行时不必强制常量,这只是一种奖励,当强制不应该是权利时。

这不是CLR给出这个错误消息它是编译器。

在第一个示例中,编译器将32视为ulong (或者可以隐式转换为ulong的类型,例如uint ),而在第二个示例中,您已将类型显式声明为int 。 接受ulongint>运算符没有重载,因此会出现编译器错误。

rich.okelly和rawling的答案是正确的,为什么你不能直接比较它们。 您可以使用Convert类的ToUInt64方法来提升int。

 if (mask > 0 & (ulong)Permissions.ViewListItems > Convert.ToUInt64(compare)) { }