Instead of splitting each permission into individual columns or sql server table we are rethinking of using Flag
attribute to Enum
for use with bit wise operations. Our application defines end points ( not the one from rest services) for accessing resources( read, modify, update) and each user is entitled with permissions for example Bob has permissions to Read, Modify resource X
so when bob comes and accesses this resource we check if bob has permission x.Now that where we are going to apply this is clear here are my doubts
Suppose Bob has Read, Write, Delete permission on resource using Flagged enumerations i would do Permission.Read | Permission.Write | Permission.Delete
Is the end result of bit wise AND a integer or another Enum ?
For Storing this permission in database table should the column be a integer
?
If answer to question 1 is Enum
then should i define another property on the Permissions
enum that represents the integer value of Bit wise and operation?
disclaimer:
the Bob referred to in the example does not represent any user in the Stack overflow network of sites or any person. It is just another character
To answer your questions in order:
Assuming you have set the [Flags]
attribute on the enum
, and use the correct operator (&
and |
for bitwise operations) it is essentially both. If you cast the result to an integer, you will get the bitwise and of the relevant values, ie. 7 for your example. If you use .ToString()
, then you will get a string back indicating that the value has all three values. I believe that there is a HasFlags()
method somewhere, but most code I have seen uses the tried and true bitwise code for comparisons, ie:
var x = Permissions.Read | Permissions.Write;
if ((x & Permissions.Read) == Permissions.Read) { print "Success!"; }
From a technical standpoint, C#'s type safety helps keep things sane and the result of |
ing or &
ing two enum
s of the same type is another enum
of the same type but all enum
s are simply integers, and can be treated as such in most cases, though some things need explicit casts to/from int
.
It should be an integral type, yes. I believe the default type for an enum is Int32
, however you can set that explicitly if you want to match up the database and code exactly.
Given all the above, it can still make a lot of sense to have predefined values for commonly used sets of permissions, for example ReadWrite
. In particular, a None
element is recommended for all enums by Microsoft, especially if you are going to be casting values. This allows for a fallback and a valid value for freshly initialized variables as well as a sane value for default(Permissions)
. You can set values in your enum based on other ones like so:
[Flags]
enum Permissions {
None = 0,
Read = 0x001,
Write = 0x010,
Execute = 0x100,
ReadWrite = Read | Write,
// [snip]
}
Normaly you define such enums with FlagsAttribute i.e.
[Flags] enum My {
None = 0, Read =1, Write =2, Delete = 4
};
When defined this way you can combine different values with | (or) operation:
My readAndWrite = My.Read | My.Write;
Bitwise AND will give you 0 for enum values that represent unique flags, but commonly used to mask other bits:
bool doIHaveWrite = (readAndWrite & My.Write) == My.Write;
Note that logical AND (&&) can't be applied to enum values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With