【问题标题】:C# performing bitwise operation with & from C++C# 使用 C++ 中的 & 执行按位运算
【发布时间】:2012-07-31 21:53:25
【问题描述】:

无论如何,这是我的问题,我一直在修改整个 C++ 程序以在 C# 中工作,我已经完成了,我在 C++ 程序中有这个 If 语句。

if(info[i].location & 0x8 || 
             info[i].location & 0x100|| 
                     info[i].location & 0x200)
{
    //do work
}
else
{
    return
}

当然,当我在 C# 中执行此操作时,它会给我一个“运算符'||'不能应用于“int”和“int”类型的操作数”错误。

关于我的问题的任何线索,我猜 C# 有办法做到这一点,因为我对这些旧的 C 运算符相当不熟悉。

【问题讨论】:

    标签: c# c++ bit-manipulation operator-keyword


    【解决方案1】:

    为什么会失败

    基本上和这个是一样的:

    if (someInteger) // C or C++
    

    if (someInteger != 0) // C#
    

    基本上,C# 在逻辑运算符和条件方面要严格得多 - 它迫使您使用 bool 或可转换为 bool 的东西。

    顺便说一句,这也是为什么在 C# 中这不仅仅是一个警告,而是一个全面的错误:

    int x = ...;
    if (x = 10) // Whoops - meant to be == but it's actually an assignment
    

    如果您以这种方式看到比较:

    if (10 == x)
    

    通常是开发人员试图避免出现上述错误 - 但在 C# 中不需要这样做,除非您真的与常量 bool 值进行比较。

    解决问题

    我怀疑你只需要:

    if (((info[i].location & 0x8) != 0)) ||
        ((info[i].location & 0x100) != 0)) ||
        ((info[i].location & 0x200) != 0)))
    

    您可能不需要 all 这些括号......但另一种选择是使用 one 测试:

    if ((info[i].location & 0x308) != 0)
    

    毕竟,您只是在测试是否设置了这三个位中的任何一个...

    您还应该考虑使用基于标志的枚举:

    [Flags]
    public enum LocationTypes
    {
        Foo = 1 << 3; // The original 0x8
        Bar = 1 << 8; // The original 0x100
        Baz = 1 << 9; // The original 0x200
    }
    

    那么你可以使用:

    LocationTypes mask = LocationTypes.Foo | LocationTypes.Bar | LocationTypes.Baz;
    if ((info[i].location) & mask != 0)
    

    或者使用Unconstrained Melody:

    LocationTypes mask = LocationTypes.Foo | LocationTypes.Bar | LocationTypes.Baz;
    if (info[i].location.HasAny(mask))
    

    【讨论】:

    • 或者甚至更好——将每个位定义为常量和按位——或者将它们一起放入掩码中进行比较
    • @DougT.:这几乎就是我上次编辑的内容 - 但不是几个整数常量,而是使用枚举。
    • 非常感谢您提供非常详细的回答。
    【解决方案2】:

    这几乎就是它所说的:在 C# 中,|| 是一个纯逻辑运算符,因此不能在 int 上工作。您可以将|| 替换为|(适用于ints 的按位或),但随后需要通过将其与零进行比较来将整个表达式转换为布尔值,因为在C# 中if-statements需要一个布尔值。

    或者,您可以将info[i].location &amp; 0x8 替换为(info[i].location &amp; 0x8 != 0)

    【讨论】:

    • +1,更好的答案,因为它解释了编译器给出错误的原因。
    • Jon Skeet 速度更快
    猜你喜欢
    • 1970-01-01
    • 2012-10-03
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多