14

Given this enum

public enum UserStatus : byte { Approved = 1, Locked = 2, Expire = 3 } 

why does this check always return false when usr.Status = 1

if(usr.Status.Equals(UserStatus.Approved)) return true; return false; 

The comparison seems to work - there is no compile time error or runtime exception. Please note I am not the author of this piece of code and would like to find out why the author chose enum of type byte and why this doesn't work as it should.

1
  • 3
    Re "no error"; since you are using the boxed version, almost anything is legal. If, however, you use the more-appropriate ==, it will tell you: Error [number] Operator '==' cannot be applied to operands of type 'byte' and 'UserStatus' Commented Jul 6, 2011 at 12:35

3 Answers 3

16

Because you will have to cast.

The equals method will check if UserStatus is an int (depending on the type you have defined at the property usr.Status). It will then return that is not (it is of type UserStatus) thus return false

Better code would be:

return usr.Status == (int)UserStatus.Approved; 
Sign up to request clarification or add additional context in comments.

4 Comments

Even better would be to declare your Status as UserStatus and not just int. After all, it represents a UserStatus, isn't it?
Also, if you used usr.Status == UserStatus.Approved then the compiler would warn you about these sorts of things.
@Vlad that is true. The reason I wrote it that way was because he didn't post the code. It also could be a generated class, from linq for example, where you cannot set the type to UserStatus
Re better code... as per my comment on the question, I would advise == here, since the compiler will report errors on ==, but not on Equals
8

The first thing any Equals implementation usually checks is: "is this the right type". And UserStatus is not the same as byte.

(actually, this only happens because you have boxed the items via your incompatible use of Equals; at the IL level they are indistinguishable until boxed)

You must compare them as items of the same type. To borrow some code from byte:

public override bool Equals(object obj) { return ((obj is byte) && (this == ((byte) obj))); } 

2 Comments

So basically casting the enum to byte before the comparison? Internal value will not change given that it will still be a byte right?
@JohnDemetriou from object to an enum or to byte is an unboxing operation - it will extract the internal value (from the box) as the enum-type or byte. That doesn't change the value in the box in any way - it is untouched. The extracted value is just a raw primitive value (in this case, on the stack). It will have the same underlying value as it had before. If that isn't what you were asking, can you be more specific?
0

That is because the Usr.Status contains an Integer and the UserStatus.Approved returns an String i.e., Approved. So, an integer of value 1 can not be equal to the String Approved. So, you must convert the Enum status also to an integer by the following code

if (usr.Status == (int)(UserStatus.Approved)) return true; return false; 

3 Comments

Enum values are never strings, you chose the storage type in the declaration. Even if they were, you can't cast a string to an integer, so your solution would not work ;-)
Here the Casting is done not to the String but to the Status of the "Approved" in UserStatus Enum, so it will return 1.
Yes, and you just said above UserStatus.Approved always returns a string, which would not be castable. Mind you, your solution works, but your explanation is just plain wrong.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.