Que faire quand le masque de bits (drapeaux) enum est trop grand
J'ai un très grand ensemble d'autorisations dans mon application que je représente avec un Drapeaux de l'énumération. Il s'approche rapidement de la pratique à la limite supérieure du type de données long. Et je suis obligé de venir avec une stratégie de transition vers une structure différente bientôt. Maintenant, je pourrais diviser cette liste en petits morceaux, cependant, déjà, c'est juste un sous-ensemble de l'ensemble des autorisations pour notre application, basée sur nos applications de mise en page. Nous utilisons cette distinction largement pour l'affichage et la gestion des autorisations et je préfère ne pas avoir à revoir le code à ce moment si je peux l'éviter.
Quelqu'un d'autre a rencontré ce problème? Comment avez-vous passé? Des exemples généraux sont beaux, mais je suis plus intéressée par un c# spécifiques, par exemple si il y a n'importe quelle langue spécifique des trucs que je peux employer pour obtenir le travail fait.
Peut ne pas être nécessaire, mais voici la liste des Autorisations actuellement définis pour la partie de l'application que je fais affaire avec.
//Subgroup WebAgent
[Flags]
public enum WebAgentPermission : long
{
[DescriptionAttribute("View Rule Group")]
ViewRuleGroup = 1,
[DescriptionAttribute("Add Rule Group")]
AddRuleGroup = 2,
[DescriptionAttribute("Edit Rule Group")]
EditRuleGroup = 4,
[DescriptionAttribute("Delete Rule Group")]
DeleteRuleGroup = 8,
[DescriptionAttribute("View Rule")]
ViewRule = 16,
[DescriptionAttribute("Add Rule")]
AddRule = 32,
[DescriptionAttribute("Edit Rule")]
EditRule = 64,
[DescriptionAttribute("Delete Rule")]
DeleteRule = 128,
[DescriptionAttribute("View Location")]
ViewLocation = 256,
[DescriptionAttribute("Add Location")]
AddLocation = 512,
[DescriptionAttribute("Edit Location")]
EditLocation = 1024,
[DescriptionAttribute("Delete Location")]
DeleteLocation = 2048,
[DescriptionAttribute("View Volume Statistics")]
ViewVolumeStatistics = 4096,
[DescriptionAttribute("Edit Volume Statistics")]
EditVolumeStatistics = 8192,
[DescriptionAttribute("Upload Volume Statistics")]
UploadVolumeStatistics = 16384,
[DescriptionAttribute("View Role")]
ViewRole = 32768,
[DescriptionAttribute("Add Role")]
AddRole = 65536,
[DescriptionAttribute("Edit Role")]
EditRole = 131072,
[DescriptionAttribute("Delete Role")]
DeleteRole = 262144,
[DescriptionAttribute("View User")]
ViewUser = 524288,
[DescriptionAttribute("Add User")]
AddUser = 1048576,
[DescriptionAttribute("Edit User")]
EditUser = 2097152,
[DescriptionAttribute("Delete User")]
DeleteUser = 4194304,
[DescriptionAttribute("Assign Permissions To User")]
AssignPermissionsToUser = 8388608,
[DescriptionAttribute("Change User Password")]
ChangeUserPassword = 16777216,
[DescriptionAttribute("View Audit Logs")]
ViewAuditLogs = 33554432,
[DescriptionAttribute("View Team")]
ViewTeam = 67108864,
[DescriptionAttribute("Add Team")]
AddTeam = 134217728,
[DescriptionAttribute("Edit Team")]
EditTeam = 268435456,
[DescriptionAttribute("Delete Team")]
DeleteTeam = 536870912,
[DescriptionAttribute("View Web Agent Reports")]
ViewWebAgentReports = 1073741824,
[DescriptionAttribute("View All Locations")]
ViewAllLocations = 2147483648,
[DescriptionAttribute("Access to My Search")]
AccessToMySearch = 4294967296,
[DescriptionAttribute("Access to Pespective Search")]
AccessToPespectiveSearch = 8589934592,
[DescriptionAttribute("Add Pespective Search")]
AddPespectiveSearch = 17179869184,
[DescriptionAttribute("Edit Pespective Search")]
EditPespectiveSearch = 34359738368,
[DescriptionAttribute("Delete Pespective Search")]
DeletePespectiveSearch = 68719476736,
[DescriptionAttribute("Access to Search")]
AccessToSearch = 137438953472,
[DescriptionAttribute("View Form Roles")]
ViewFormRole = 274877906944,
[DescriptionAttribute("Add /Edit Form Roles")]
AddFormRole = 549755813888,
[DescriptionAttribute("Delete UserFormRolesDifferenceMasks")]
DeleteFormRole = 1099511627776,
[DescriptionAttribute("Export Locations")]
ExportLocations = 2199023255552,
[DescriptionAttribute("Import Locations")]
ImportLocations = 4398046511104,
[DescriptionAttribute("Manage Location Levels")]
ManageLocationLevels = 8796093022208,
[DescriptionAttribute("View Job Title")]
ViewJobTitle = 17592186044416,
[DescriptionAttribute("Add Job Title")]
AddJobTitle = 35184372088832,
[DescriptionAttribute("Edit Job Title")]
EditJobTitle = 70368744177664,
[DescriptionAttribute("Delete Job Title")]
DeleteJobTitle = 140737488355328,
[DescriptionAttribute("View Dictionary Manager")]
ViewDictionaryManager = 281474976710656,
[DescriptionAttribute("Add Dictionary Manager")]
AddDictionaryManager = 562949953421312,
[DescriptionAttribute("Edit Dictionary Manager")]
EditDictionaryManager = 1125899906842624,
[DescriptionAttribute("Delete Dictionary Manager")]
DeleteDictionaryManager = 2251799813685248,
[DescriptionAttribute("View Choice Manager")]
ViewChoiceManager = 4503599627370496,
[DescriptionAttribute("Add Choice Manager")]
AddChoiceManager = 9007199254740992,
[DescriptionAttribute("Edit Chioce Manager")]
EditChoiceManager = 18014398509481984,
[DescriptionAttribute("Delete Choice Manager")]
DeleteChoiceManager = 36028797018963968,
[DescriptionAttribute("Import Export Choices")] //57
ImportExportChoices = 72057594037927936
}
- Pour plus de clarté, j'ai l'habitude d'utiliser: (1 << 0), (1 << 1), .. (1 << 57) pour mes drapeaux. Plus facile à comprendre et plus dur pour obtenir la valeur de mal. Ne pas répondre à votre question, cependant.
- merci, j'avais essayé un peu de moyens pour faire quelque chose de similaire, mais j'ai toujours eu ne pouvez pas utiliser la valeur calculée pour les enums erreur.
- Vraiment? Pouvez-vous me montrer un exemple? Il devrait être légal pour utiliser les valeurs calculées dans une phase d'initialisation pour un membre enum, tant que cela ne cause pas de boucles dans la chaîne de dépendances.
- Eh bien, je rétracte mon intervention précédente. J'ai probablement essayé quelque chose comme (long)Math.Pow(2,2) avant de tester les eaux, qui échoue avec 'Expression attribuée à ... doit être constante.' Je suis sûr que je n'ai pas réussi à tester autre chose, merci de m'appeler sur elle. J'ai appris quelque chose.
- Il est à noter que (1 << n) pour 32 drapeaux, mais ensuite les répéter que la position du bit wraps au début du mot. J'ai utilisé (2 ^ n) à la place.
- Je pense ^ ne signifie pas ce que vous pensez que cela signifie.
- Si vous voulez faire un long bitshift, indiquer au compilateur qu'est ce que vous voulez. (1L << 40) devrait fonctionner parfaitement.
- Eh bien, explative, C'est ce que je reçois pour se précipiter à travers ce, merci encore pour pointer quelque chose de stupide, je n'ai sorti 🙂
- Aujourd'hui j'ai appris quelque chose aujourd'hui est une bonne journée! Donc beaucoup plus facile à lire & ne pas avoir à utiliser de feuille de calcul pour calculer les nombres afin de m'assurer de le faire!
Vous devez vous connecter pour publier un commentaire.
Je vois des valeurs d'au moins une poignée de différentes énumérations là...
Ma première pensée a été d'aborder le problème en divisant les autorisations en groupes logiques (
RuleGroupPermissions
,RulePermissions
,LocationPermissions
, ...) et puis d'avoir une classe (WebAgentPermissions
) exposer une propriété pour chaque autorisation de type enum.Depuis la permission valeurs semblent répétitives, vous pouvez probablement vous en sortir avec une simple enum à la fin:
Et ensuite le
WebAgentPermissions
classe exposer une propriété pour chaque zone où les autorisations sont à définir;Documentation sur le langage dit:
http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx
"Le sous-jacent est de type Int32 et donc le maximum de bit unique drapeau est 1073741824 et, évidemment, il y a un total de 32 drapeaux pour chaque enum."
Cependant... mise à JOUR:
Intervenant est correct. Découvrez ce:
http://msdn.microsoft.com/en-us/library/ms182147(SV.80).aspx
Int32 est seulement le type de données par DÉFAUT! En fait, vous pouvez spécifier Int64.
...permettre à un maximum de 64 valeurs. Mais cela semble être le maximum, après que vous allez être à la recherche à la ré-ingénierie. Sans savoir trop sur le reste de votre solution, je ne peux pas dire exactement ce que pourrait convenir. Mais un tableau (ou hash-plan) de privilège identifiants est probablement le plus naturel de l'approche.
public enum WebAgentPermission : long
et qui est le même que l'utilisation deInt64
((p.group | p.location) & MY_PERMISSION) == MY_PERMISSION
) tu sais?Vous pouvez vérifier BitArray classe. Peut-être que vous allez utiliser dans le futur.
En C#, un flexible de façon à représenter une valeur qui est en quelque sorte d'une énumération, mais plus souple consiste à la représenter comme une classe statique avec précuit valeurs disponibles, comme ceci:
Sinon, juste diviser la chose; il semble que vous pouvez, si vous avez vraiment essayé.
Si j'étais dans le contrôle de cette application, je serais probablement venir avec un ensemble commun d'autorisations (Afficher, Ajouter, Modifier, Supprimer, Télécharger/Importation) et un ensemble de ressources (les Utilisateurs, les Rôles, les Règles, etc). Sur la page web trouver le type de ressource associée à cette page, puis de vérifier les autorisations. Peut-être quelque chose comme:
ou
ou même
Vous avez un couple d'autorisations qui n'ont pas de sens avec tout le reste (à Affecter Permissoins à l'utilisateur, au nom de l'un). Je ne suis pas sûr de savoir comment je réagirais, basé sur la façon dont je connais le problème.
Je n'ai pas été dans cette situation.
Voici ce que je pense, de créer des énumérations pour chaque catégorie & accepter ceux que paramètres.
EDIT: Regardez comment messagebox.montrer t-il. OK, OKCancel séparée de la Question, d'Informations, de points d'Exclamation.