5

So I have some code in VB that I am trying to convert to C#. This code was written by someone else and I am trying to understand it but with some difficulty. I have some bitwise operator and enum comparison to do but keep throwing an error out:

I cannot say that i have used a lot of these syntaxes before and am baffled how to write this code. I have used Google to understand more about it and also used VB to C# online converters in the hopes of getting some basic guidance but nothing. The code below

VB - This is the original code that works

Flags = Flags And Not MyEnum.Value ' Flags is of type int

C# -the code I converted which is throwing an error

Flags = Flags & !MyEnum.Value; // Flags is of type int

Error - The error that is returned every time

Operator '!' cannot be applied to operand of type MyEnum'.

Any help and some explanation on this will be greatly appreciated.

Waqas Shabbir
  • 755
  • 1
  • 14
  • 34
Mo Patel
  • 2,321
  • 4
  • 22
  • 37

3 Answers3

8

! can only operate on bool type. You seem to be operating on some bit flags. In that case you should use the bitwise NOT operator ~ instead of the logical NOT operator !:

Flags = Flags & ~((int)MyEnum.Value); // you need to cast to int as well
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • You'll need a cast of the enum value to an int. – Dave Doknjas Jan 05 '19 at 01:05
  • @DaveDoknjas why do you say that? I believe that is not true, as the underlying type of the enum would be an `int` and thus the `~` operator works just fine without casting. – Kirk Woll Jan 05 '19 at 01:47
  • @KirkWoll: The bitwise operator '&' is not defined for int and any enum (this is the actual error you'll get), so you need to cast. – Dave Doknjas Jan 05 '19 at 02:08
  • @DaveDoknjas not sure what you're talking about. This works perfectly fine: `var foo = Foo.A | Foo.B; foo = foo & ~Foo.A;` Where `Foo` is declared as an `enum`. – Kirk Woll Jan 05 '19 at 02:10
  • Furthermore, of _course_ `&` is defined for `int`. `int i = 0 & 5;` is perfectly valid. – Kirk Woll Jan 05 '19 at 02:11
  • @KirkWoll Dave Doknjas is correct. All enums have a `~` operator that returns an enum, but overload resolution for `&` fails when you have an `int` and a `MyEnum`. Read the language spec section 7.5.3. – Sweeper Jan 05 '19 at 02:30
  • @Sweeper, like I said, `foo = foo & ~Foo.A` works perfectly fine. Am I missing something? – Kirk Woll Jan 05 '19 at 02:30
  • 1
    @KirkWoll: In your example, "foo" is not an int as in Sweeper's example - you'll notice that it's type is "Foo". If you change "foo" to be of type int, you'll see the problem. In Sweeper's example, "Flags" is of type int. – Dave Doknjas Jan 05 '19 at 02:31
  • Ah, thank you! You are both right. But it leaves the question as to why `Flags` is not declared as the actual enum type in that case where none of this would be necessary. – Kirk Woll Jan 05 '19 at 02:33
6

To get the best conversion, it helps to first understand the implicit conversion that VB is doing for you:

Flags = Flags And Not (CInt(MyEnum.Value))

This is equivalent to the C# code:

Flags = Flags & ~(int)MyEnum.Value;

Which can be shortened:

Flags &= ~(int)MyEnum.Value;

In VB, "Not" is both the logical and bitwise operator, depending on context, but in C# you have two distinct operators.

Dave Doknjas
  • 6,394
  • 1
  • 15
  • 28
5

You maybe confusing Logical and Bitwise unary operators

Lets visit the help

Operators (C# Programming Guide)

Unary Operators

  • +x Identity
  • -x Negation
  • !x Logical negation
  • ~x Bitwise negation
  • ++x Pre-increment
  • --x Pre-decrement
  • (T)x Explicitly convert x to type T

Compiler Error CS0023

Operator 'operator' cannot be applied to operand of type 'type'

An attempt was made to apply an operator to a variable whose type was not designed to work with the operator.

TheGeneral
  • 79,002
  • 9
  • 103
  • 141