Enumeration of flags without the power of two values

The MSDN documentation for the Flag attribute says you should:

Determine the enumeration constants by the powers of two, that is, 1, 2, 4, 8, and so on. This means that the individual flags in the combined enumeration of constants do not overlap.

... and, of course, I always try to keep that in mind. However, nothing will provide this, and if you just create an enumeration of the "main" way, for example ...

 [Flags] public enum BrokenEnum { None, FirstOption, SecondOption, ThirdOption } 

... he will not behave as expected. To combat this, I am looking for some kind of static code analysis (like FxCop ) that can warn me when an enumeration like the one described above exists in my code. The closest warning I could find was ' CA1008: Enums should be zero ' - which is also useful for flag counting correctly, but not enough.

What is the best way to find malformed checkboxes in my code? The more automated the solution, the better.

+6
source share
3 answers

As Jacob says, it may be useful to have a mixture of flags ... but perhaps you could indicate that one way or another so that your discovery does not mind.

You cannot write a unit test that goes through each enumeration in an assembly decorated with [Flags] and checks if there is a value for 0 (it is possible that it should be called None or Default ) and that any other specific value (from Enum.GetValues() ) is a power of two. You can verify that with if ((x & (x - 1)) == 0) .

You might have something like the [Combination] attribute to indicate values ​​that are for combinations ... they can even indicate which flag names they should be combinations, so you can check that too.

I know that this is not as good as checking compile time, but assuming you already run the tests regularly, it's pretty close.

+2
source

Sometimes you want to have a flag enumeration that presents several options; in such cases this is not a mistake. Here is a general example:

 [Flags] public enum FilePermissions { None = 0, Read = 1, Write = 2, Execute = 4, ReadWrite = 3, // Read | Write, ReadWriteExecute = 7 // Read | Write | Execute } 

Perhaps because of the need to support cases where the compiler does not raise a warning or error.

+3
source

I have never tried this on my own, but maybe you could write your own rule for FxCop.

Check FxCop and code analysis: writing your own custom rules .

+3
source

Source: https://habr.com/ru/post/895471/


All Articles