问题
I have the following enum:
[Flags]
public enum PermissionLevel {
User = 1,
Administrator = 2,
ITStaff = 3,
Manager = 4,
SuperAdministrator = 6,
}
When I do:
PermissionLevel permission = (PermissionLevel) dr.GetInt32(i);
I get random permission values assigned to the permission object. For instance, if i is 6, my permission object returns "Administrator | Manager" and I'm supposed to get "SuperAdministrator". When I cast the instance back to integer it returns 6.
Am I missing something?
回答1:
You need to make sure that each combination of values is unique:
[Flags]
public enum PermissionLevel {
User = 1,
Administrator = 2,
ITStaff = 4,
Manager = 8,
SuperAdministrator = 16
}
As your enum currently looks, 6 can mean either SuperAdministrator or Administrator | Manager. 4 can be either Manager or User | ITStaff and so on.
回答2:
There's nothing random about it. If permission is 6, the binary value is 110. There are two active flags (bits with a value of 1), the bit with the value of 4 (Manager), and 2 (Administrator). The SuperAdministrator value of 6 that you set is actually a combination of Manager and Administrator.
Sometimes that's the behavior that you want, but it doesn't seem to be your case. You should then change your enum so that each value represents a unique bit, as other answers demonstrate.
回答3:
when decorated with the Flags attribute, you can do what you are doing and it's perfectly fine.. The CLR is telling you that the value assigned to the enum instance is and Administrator Or a Manager... thats what the vertical pipe is, a bitwise Or operator.
From the msdn page msdn Flags Attribute
"Consider creating an enumerated constant for commonly used flag combinations. For example, if you have an enumeration used for file I/O operations that contains the enumerated constants Read = 1 and Write = 2, consider creating the enumerated constant ReadWrite = Read OR Write, which combines the Read and Write flags. In addition, the bitwise OR operation used to combine the flags might be considered an advanced concept in some circumstances that should not be required for simple tasks."
You could have just as easily have declared the enum as follows:
[Flags]public enum PermissionLevel
{
User = 1,
Administrator = 2,
ITStaff = User | Administrator,
Manager = 4,
SuperAdministrator = Administrator | Manager ,
}
and oh, btw, it's considered good practice to always include a None value...
[Flags]public enum PermissionLevel
{
None = 0,
User = 1,
Administrator = 2,
ITStaff = User | Administrator,
Manager = 4,
SuperAdministrator = Administrator | Manager ,
}
This technique is extremely useful, as it allows client code to test a candidate value against a subset of the individual values using syntax that concisely expresses the actual business intent... assuming candValue is one of core individual values...
if ((candValue & PermissionLevel.SuperAdministrator) == candVal)
// tests to see if candValue is Administrator Or Manager
which would require 2 comparisons if you did not have access to an enum value that represented the SuperAdministrator bitmask = 00000110
来源:https://stackoverflow.com/questions/1596735/bitwise-enum-cast-return-value-not-expected