" I"除非非整数而非bool类型的运算符

时间:2015-08-10 13:11:12

标签: c# operators

我试图了解,在哪里使用|运营商。在msdn,有人告诉

  

二进制|运算符是为整数类型和bool预定义的。

  

用户定义的类型可能会使|运算符

重载

所以,当我看到类似的东西时:  BindingFlags.CreateInstance | BindingFlags.ExactBinding

 NotifyFilters.Attributes | NotifyFilters.FileName | NotifyFilters.LastAccess

我认为这是重载|运算符和逻辑将类似:somthing或其他等等。但是,我如何指出为某些类定义了运算符|

3 个答案:

答案 0 :(得分:1)

这意味着,枚举值是"组合"使用or - 运算符。想象一下:

public enum MY_ENUM
    : int
{
    FOO = 1,
    BAR = 2,
    TEST = 4,
    ALL_VALUES = 7,
}

FOO | BAR | TEST将等于ALL_VALUES,如以下计算所示:

result := FOO | BAR | TEST
        =  1  |  2  |  4    // <-- this is a normal OR-operation
        = 7

  --> result == ALL_VALUES

结论:枚举的所有值都会被处理为&#34; normal&#34;整数,可以与任何二进制或数学运算符一起使用。

<小时/> See this msdn article

<小时/> 编辑:如果您希望在枚举变量上更好地输出二进制运算,也可以在枚举上使用[Flags] - 属性。

答案 1 :(得分:1)

不,这些enum在内部表示为int。 (您可以毫无问题地将这些enum转换为int,反之亦然。)此类int s / enums称为标记。在像C这样的其他语言中,没有额外的enum类型,因此它们只是普通的int或其他整数类型。

所以你的第一句话中所述的情况仍然如此:

  

二进制|运算符是为整数类型和bool预定义的。

提出其他问题

  

但是如何指示运算符|是为某些类定义的?

使用operator关键字重载运算符。注意:并非每个运算符都是可重载的,请参阅here

// example addition operator from a complex number class
public static Complex operator +(Complex c1, Complex c2)
{
    Return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);
}

您可以使用Reflection在运行时确定某个类是否实现了某个运算符。在内部,运营商只是方法。例如,==运算符在方法op_Equality中实现。因此,如果存在这样的方法,则==运算符可用。 (你只能看到那些带有反射的方法,它们在普通的C#代码中是不可调用的)。来自Reflection API的See GetMethod()如何确定运算符的存在。

+运算符的代码示例

MethodInfo operator = typeof(YourClass).GetMethod("op_Addition");

if (operator != null) // if null the operator is not implemented
   operator.Invoke(null, firstInstance, secondInstance);

我不知道|运算符的方法名称是什么,但您可以使用反编译工具轻松检查它。它应该是op_BinaryOr

如果您只想知道是否可以在代码中使用运算符,则应由IDE提供,Visual Studio例如在IntelliSense自动完成列表或对象浏览器中显示运算符。

答案 2 :(得分:1)

是。这样做没有多大意义,但你绝对可以覆盖|操作者:

public static MyClass operator |(MyClass left, MyClass right)
{
    //your logic here
}

基本上该运算符的作用是它结合了两个整数的十六进制值,如下所示:

int a = 0x0402;  //1026
int b = 0x5030;  //20528
int c = a | b;   //21554 (same as a+b)
string hex = "0x"+ c.ToString("X4"); //0x5432

但请勿将其与+运算符

混淆
int a = 0x0007;  //7
int b = 0x000B;  //11
int c = a | b;   //15 (a+b would be 0x0012)
string hex = "0x"+ c.ToString("X4"); //0x000F

对于枚举,基础值是得到的-d
这是一个例子

        [Flags]
        enum ActionFlags : int
        {
            DoThis = 0x00000001,
            DoThat = 0x00000010,
            DoOtherThing = 0x00000100,
            DoAnotherThing = 0x00001000,
            MaxValue = 0x00001111,
            MinValue = 0x00000000,
        }

        void DoStuff(ActionFlags what_to_do)
        {
            if ((int)(what_to_do) > (int)(ActionFlags.MaxValue) || 
                (int)(what_to_do) < (int)(ActionFlags.MinValue))
                throw new ArgumentException();
            if(what_to_do.HasFlag(ActionFlags.DoThis))
            {
                // do this
            }
            if (what_to_do.HasFlag(ActionFlags.DoThat))
            {
                // do that
            }
            if (what_to_do.HasFlag(ActionFlags.DoOtherThing))
            {
                // do other thing
            }
            if (what_to_do.HasFlag(ActionFlags.DoAnotherThing))
            {
                // do another thing
            }
        }


DoStuff(ActionFlags.DoThat | ActionFlags.DoOtherThing);

你不应该打扰自己的原因,就像msdn所说,它已经为所有数字类型预定义了,对于大多数其他类,这种二进制逻辑是不必要的。