运算符">"不能应用于'ulong'和'int'类型

Ami*_*ble 26 .net c#

我很想知道为什么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'
    }
}
Run Code Online (Sandbox Code Playgroud)

Raw*_*ing 32

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

显然,在你的第二种情况下,这是一个错误 - 你无法比较a ulong和a ,int因为没有你可以强制执行的类型.A ulong可能对a来说太大了long,而且int可能是负面的.

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

但那么编译器是否成功地将a ulong与a进行比较int,我们刚才说这是不可能的?

显然不是.那怎么回事?

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

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

这将编译,即使它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);
}
Run Code Online (Sandbox Code Playgroud)

所以,编译器实际上将你const int视为一个ulong.如果你做了thirtytwo = -1,代码就无法编译,即使我们知道这gt永远是真的.编译器本身无法将a与a ulong进行比较int.

还要注意的是,如果你做x一个long,而不是一个ulong,编译器生成32L,而不是32一个整数,尽管它不具备对.(您可以在运行时比较a int和a long.)

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

  • C# 编译器与此处的 C# 语言规范完全一致。当“int”类型的表达式是编译时常量时,确实存在从“int”的[隐式常量表达式转换](http://msdn.microsoft.com/en-us/library/aa691286.aspx)到 `ulong` _前提是该值在 `ulong` 的范围内_,即非负数,这是 C# 编译器可以通过常量表达式看到的内容。`32` 是 `int` 类型的常量表达式。当“int”类型的表达式不是编译时常量时,不存在到“ulong”的隐式转换。例如“比较”。 (2认同)

Ric*_*lly 21

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

在你的第一个例子中,编译器将32作为ulong(或类型的隐式转换为ulonguint),而在第二个例子中,你已经明确声明的类型为int.>接收a ulong和a 的运算符没有重载,int因此会出现编译错误.

  • 整数文字页面(http://msdn.microsoft.com/en-us/library/aa664674.aspx)说"如果文字没有后缀,则它具有可以表示其值的第一种类型:int ,uint,long,ulong." 加上我的Intellisense(工具提示)说`32`是一个`int`.但这似乎正在发生的事情...... (7认同)