HasFlag не распознает назначение роли - PullRequest
2 голосов
/ 17 января 2011

Я использую Enum, украшенный [Flags], для управления автоматизацией в моем приложении MVC2. Ниже приведены примеры кода:

[Flags]
public enum SecurityRoles
{
    None = 0,
    Executive = 1,
    BackOffice = 2,
    AccountManager = 4,
    Consultant = 8,
    Administrator = 16
}

[TestMethod]
public void MultipleSelectionsTest()
{
    var requiredRoles = SecurityRoles.Executive | SecurityRoles.BackOffice;
    var user1Roles = SecurityRoles.Executive | SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant;
    var user1HasAccess = user1Roles.HasFlag(requiredRoles);

    var user2Roles = SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant;
    var user2HasAccess = user2Roles.HasFlag(requiredRoles);


    Assert.IsTrue(user1HasAccess);  //returns true
    Assert.IsTrue(user2HasAccess);  //returns false
}

Как видите, user2Roles содержит роль BackOffice, а requiredRoles также содержит роль BackOffice, однако user2HasAccess имеет значение false. Это почему? Что мне не хватает? user1HasAccess имеет значение true.

Ответы [ 2 ]

3 голосов
/ 17 января 2011

Поправьте меня, если я ошибаюсь (потому что мог бы быть), но когда вы выполняете проверки флагов Enum, .NET по существу выполняет двоичную арифметику с целым числом, которое представляет сумму флагов.

То есть значение SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant - это то же самое, что значение 26 или 11010 в двоичном виде.

Когда вы вызываете Enum.HasFlags, выполняется операция return thisInstance & flag == flag

Таким образом, если вы проверяете ранее упомянутый флаг, установленный для требуемых ролей SecurityRoles.Executive | SecurityRoles.BackOffice, значение 3 или 11 в двоичном формате, математика выглядит примерно так:

11010 - 26 Administrator | BackOffice | Consultant
00011 -  3 Executive | BackOffice
----- 
00010 -  2 BackOffice which really doesn't mean anything useful

Тогда из этого следует, что 26 & 3 == 3 ложно.

И ради тщательности, учитывая SecurityRoles.Executive | SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant значение 27 или 11011 в двоичном виде, математика выглядит так:

11011 - 26 Executive  | Administrator | BackOffice | Consultant
00011 -  3 Executive | BackOffice
----- 
00011 -  3 Executive | BackOffice

Тогда из этого следует, что 26 & 3 == 3 истинно.

Метод расширения, похожий на этот, может быть полезным (не проверено)

public static bool HasFlags(this Enum source, Enum[] flags) 
{
    return flags.Any(f => source.HasFlag(f));
}
0 голосов
/ 18 января 2011

Спасибо за вашу помощь Уэс П. Я смог принять ваше предложение и объединить его с найденным здесь расширением: текст ссылки и придумал собственное расширение для решения проблемы

Вот мое расширение.Он использует метод GetFlags () в методах расширения, которые я нашел по ссылке выше.

public static bool HasFlags(this Enum userRoles, Enum requiredRoles)
        {
            var hasFlags = false;
            var userRolesList = userRoles.GetFlags();
            var requiredRolesList = requiredRoles.GetFlags();

            foreach (var role in userRolesList)
            {
                var role1 = role;
                hasFlags = requiredRolesList.Any(securityRole => role1.CompareTo(securityRole) == 0);

                if(hasFlags)
                    break;
            }

            return hasFlags;
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...