Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove privilege enum flags the right way in C#

Tags:

c#

.net

enums

wpf

I have an enum type for user privileges that looks like this:

[Flags]
public enum UserPrivileges : byte
{
    None = 0,                                     // 0000 0000
    View = 1 << 0,                                // 0000 0001
    Import = 1 << 1,                              // 0000 0010
    Export = 1 << 2,                              // 0000 0100
    Supervisor = View | Import | Export | 1 << 3, // 0000 1111
    Admin = Supervisor | 1 << 4                   // 0001 1111
}

These values are bound to CheckBoxes in the GUI with a value converter. (I wanted to do this as generic as possible because there are also different privileges [e.g. EmployeePrivileges])

public class ByteFlagsEnumValueConverter : IValueConverter
{
    private byte _targetValue;

    public object Convert(object value, Type targetType,
                          object parameter, CultureInfo culture)
    {
        var mask = (byte)parameter;
        _targetValue = (byte)value;
        return ((mask | _targetValue) == _targetValue);
    }

    public object ConvertBack(object value, Type targetType,
                              object parameter, CultureInfo culture)
    {
        var mask = (byte)parameter;

        if ((bool)value)
        {
            _targetValue |= mask;
        }
        else
        {
            // Get next superflag for mask (e.g. 0110 -> 1111)
            var b = mask;
            b--;
            b |= (byte)(b >> 1);
            b |= (byte)(b >> 2);
            b |= (byte)(b >> 4);
            b |= (byte)(b >> 8);

            // if you remove a superflag (e.g. 1111) also remove
            // everything higher than this flag
            if (mask == b || mask == 1)
                _targetValue &= (byte)(mask >> 1);
            else
                // ????????
        }

        return Enum.Parse(targetType, _targetValue.ToString());
    }
}

This works really fine for displaying and adding privileges to the user in the GUI. Also it works for removing Superflags like Supervisor (all flags >= Supervisor get removed, the other flags don't change).

The problem is when I uncheck Import for example, I want to remove all Superflags (Supervisor, Admin) but would like to keep the other flags (View, Export).

0001 1111 // Admin
0000 0010 // Import
---------
0000 0101 // View | Export

But I haven't come up with an good idea how to accomplish this. Anyboy who has a good solution for this?

like image 914
Staeff Avatar asked Jun 05 '13 12:06

Staeff


1 Answers

If I understand what you want , this should do the job

    byte tmp = 1 << 3 | 1 << 4;
    byte removeSuperFlagMask = (byte) (~tmp);

    byte notSuperflagsMask = 1 << 3 | 1 << 2 | 1 << 1;
    if ((valueToRemove & notSuperflagsMask) != 0)
    {
        newValue = (byte)(removeSuperFlagMask & currentValue & ~valueToRemove);
    }
like image 76
Mzf Avatar answered Oct 12 '22 09:10

Mzf