On this page, I see the following code:
if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
But I don't understand why it is the way it is.
Why attributes & FileAttributes.Hidden)
? What does the singular check on attributes
actually do? Does it check if it's not null? I have a feeling I know, but it seems weird. Random and weird.
It's simple boolean logic. The ==
operator only returns true
if both sides have the exact same value. So you have to mask the attributes
value with the flag you want to compare against. Consider those two examples (values are made up):
true:
0010001 // attributes
& 0000001 // FileAttributes.Hidden
-------
= 0000001 // FileAttributes.Hidden
false:
0011000 // attributes
& 0000001 // FileAttributes.Hidden
-------
= 0000000 // FileAttributes.None
attributes
is of FileAttributes
type. This type is an enum
, a value type. It is not FileAttributes?
(Nullable<FileAttributes>
), so it simply cannot be null.
Every enum
consists of a list of named values, but each of them is mappable/convertible to some integer (int) values. In many places C# allows you to "exploit" that conversion and (somewhat) treat enum values as if they were ints, but still they are not.
For example, the & operator performs what you'd expect - it performs binary AND. This way, if the enum value, converted to integer, has relevant bit(s) set, you will get some nonzero result.
In a "good old way" of checking if some flags/bits are present in some status value. You may often see expression like foo & FLAG != 0
which checks if the flag is set, or foo & (FLAG|BLAG) != 0
that checks if any of those two is set. This is a little flawed/dangerous because if someone changes FLAG to have more than one bit, then such expressions would check if ANY bit is set, not if the whole such "multi-bit flag" is set. That's why you may also often see foo & FLAG == FLAG
that applies the bitmask and checks if the result IS the bitmask, so it checks if all bits of mask are set.
Here, in your case it's just that. Since in that expression you are ANDing and COMPARING with the same mask, you are effectively checking if ALL bits of the mask are set. But that's superfluous as the FileAttributes is clearly marked as [Flags], the Hidden
value has just one bit, so != 0 would be enough.
However, in such cases (checking flags, not fancy bitwise masks) you may try to use Enum.HasFlag method, most people will advise you to use it, since it's designed to such cases ;)
This however is not always the best pick. Please see:
..but I would be suprised if that performance cost would be an issue to you. Optimizing to this point is very rarely needed.
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