6
votes

Supprimer Privilege Enum Flags la bonne façon en C #

J'ai un type d'enum pour les privilèges utilisateur qui ressemble à ceci:

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


9 commentaires

Essayez-vous d'éviter d'utiliser une logique conditionnelle? Si vous commencez à coder cela avec des déclarations si / elière, c'est assez simple.


Dans votre exemple, vous souhaitez supprimer admin et import ?


@Candide Je veux garder cela aussi générique que possible, afin que je puisse utiliser cela également pour d'autres projets ou des privilèges différents.


IMHO, vous abusez des énums ici qui vous causent tous les problèmes.


@MZF dans mon exemple je veux supprimer l'importation et donc aussi admin et superviseur doit être supprimé


@Danielhilgarth Que utiliseriez-vous? Parce que je pense que l'utilisation de drapeaux (peu importe si ENUM ou INT ou autre) est idéal pour cela, car vous n'avez besoin que d'un seul champ pour représenter plusieurs privilèges et peut facilement obtenir si un utilisateur a un privilège spécifique avec .HASFLAG (...)


@Staeff: Ouais, mais le problème ici est que vous essayez d'encoder la logique dans l'énum.


Je pense que le problème est lié à la définition de l'énum, ​​qui mélange des privilèges (vue, importation, exportation) avec des rôles (superviseur, administrateur).


@Staeff je pense que ma réponse est celle que vous voulez. Voir ci-dessous.


3 Réponses :


2
votes

Si je comprends ce que vous voulez, cela devrait faire le travail

    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);
    }


1 commentaires

Merci de m'avoir amené à l'idée, mais j'avais besoin d'une solution plus générique. Voir ma réponse.



1
votes

Si j'ai bien compris, vous souhaitez supprimer superviseur et admin donc: xxx

Il fonctionnera comme ceci: xxx

Un autre exemple xxx

Par reste, je veux dire que lorsque le drapeau 7 est défini, il persiste la Valeur dans le résultat (Beein 0 ou 1 ). Et où le drapeau 7 est 0 il tuera la valeur à 0 .


0 commentaires

0
votes

MFZ m'a apporté de la bonne voie mais, ce n'était pas assez générique pour moi, alors je suis venu avec Une autre solution:

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

        if ((bool)value)
        {
            _targetValue |= mask;
        }
        else
        {
            if (IsSuperFlag(mask) && mask != 1)
                _targetValue &= (byte)(mask >> 1);
            else
            {
                // Get all flags from enum type that are no SuperFlags
                var flags = Enum.GetValues(targetType).Cast<Enum>();
                flags = flags.Where(x => !IsSuperFlag(System.Convert.ToByte(x)));

                long nonSuperFlags = 0;

                foreach (var flag in flags)
                {
                    nonSuperFlags |= System.Convert.ToByte(flag);
                }

                // Now only remove everything except the nonSuperFlags
                // and then remove the mask
                _targetValue &= (byte)(~(_targetValue ^ nonSuperFlags | mask));

            }
        }

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

    private bool IsSuperFlag(byte flag)
    {
        var b = flag;
        b--;
        b |= (byte)(b >> 1);
        b |= (byte)(b >> 2);
        b |= (byte)(b >> 4);
        b |= (byte)(b >> 8);

        return b == flag;
    }


1 commentaires

C'est très loin de la meilleure façon. Mais puisque vous accomplissez votre objectif qui est la matière.