Сложность заполнения списка при сравнении массивов - PullRequest
2 голосов
/ 26 января 2011

Далее я хочу использовать GetUsersRole, но испытываю трудности с показанной частью. Я хочу сравнить значения ролей с usersRole, и если Role == usersRole, то UserRole = true, иначе false.

В основном я хочу получить что-то вроде этого в качестве результата:

user1: true

user2: ложь

пользователь 3: ложь

user4: true

в зависимости от пользователя Роль

Классовая роль

public enum Role
{                                            
    User1 = 1,
    User2= 2,
    User3= 3, 
    User4= 4
}

У меня есть класс

private class UserRoleModel
{
    public string Role { get; set; }
    public bool UserRole { get; set; }
}

и метод

public Role[] UserRoles { get; set; }  
private static UserRoleModel[] GetUsersRole(Role[]usersRole)
{
    List<UserRoleModel> rolesList = new List<UserRoleModel>();
    string[] Roles;
    Roles = new string[] { Role.user1.ToString(), Role.User2.ToString(), 
              Role.user3.ToString(), Role.user4.ToString() };
    foreach (var item in Roles)
    {
        rolesList.Add(new UserRoleModel
        {
            Role = item,
            *UserRole = usersRole.Contains(item)* ////difficulty here
        });
    }
    return rolesList.ToArray();
}

Ответы [ 4 ]

1 голос
/ 26 января 2011

Вы столкнулись с этой проблемой, потому что вы превращаете значения Role в строки, когда вам на самом деле не нужна строка.Переместите ToString() туда, где это действительно нужно:

public Role[] UserRoles { get; set; }  
private static UserRoleModel[] GetUsersRole(Role[]usersRole)
{
    List<UserRoleModel> rolesList = new List<UserRoleModel>();

    Role[] roles = (Role[]) Enum.GetValues(typeof(Role));

    // or if you need the specific three values like in your example:
    // Role[] roles = new Role[] { Role.User1, Role.User2, Role.User3, Role.User4 };

    foreach (var role in roles)
    {
        rolesList.Add(new UserRoleModel
        {
            Role = role.ToString(),
            UserRole = usersRole.Contains(role)
        });
    }
    return rolesList.ToArray();
}
1 голос
/ 26 января 2011

Проверить последнее обновление на правильный ответ

Я не понимаю, что вы пытаетесь сделать. Но из кода, показанного в вашем вопросе, я вижу, что вы вызываете метод Contains

userRole.Contains(item);

и я предполагаю, что вы пытаетесь найти item в массиве Roles Но в контексте аргумент, который вы взяли userRole, не является массивом. Исправить вместо:

private static UserRoleModel[] GetUsersRole(Role usersRole)

вы должны написать:

private static UserRoleModel[] GetUsersRole(Role[] usersRole)
<Ч />

Обновление

Хорошо, я понял .. Проблема в том, что в Contains methofd вы ищете, передавая String, где в массиве содержатся значения типа Role.

Таким образом, вопрос заключается в том, как найти экземпляр Enum в массиве экземпляров Enum из строкового представления экземпляра Enum

Обычно вы можете искать только по типу элементов в массиве, но здесь у вас есть строковое представление, так что можно сделать что-то подобное:

создать функцию:

public Role GetRole(string rolestring)
{
     Role result; 
     foreach(string rolename in Enum.GetNames(typeof(Role)))
     {
       if(rolename == rolestring)
       {
           try 
           {
             result = (Role) Enum.Parse(typeof(Role), rolename); 
           }
           catch(ArgumentException e)
           {
                 //Most unlikely we ever enter this catch s we know for sure we have role
                 //Process if role not found
                 throw;
           }
       }
     }
     return result;
}

тогда в вашем коде

UserRole = usersRole.Contains(GetRole(item));

<Ч />

Обновление

В типе Array отсутствует метод Contains

Хорошо, я понял .. Проблема в методе Contains, поскольку такого метода, как Contains для массивов типов, не существует, а для типа List<T>

Для массивов у нас есть Exists, который принимает Predicate в качестве аргумента для поиска и возврата bool.

Используйте его следующим образом:

//just to be sure correct value is captured everytime
string copy = item;
//Predicate is in System.Predicate<T>
Predicate<string> predicate = itemtocheck => {   
       itemtocheck == copy;
   };
UserRole = Array.Exists(Enum.GetNames(typeof(Role)), predicate);

<ч /> Мое первое обновление было правильным, но тогда я не заметил, что у массива нет метода Contains. Проверьте мой последний ответ правильный ответ Надеюсь, это поможет

0 голосов
/ 26 января 2011
*UserRole = usersRole.Contains(item)* ////difficulty here

Измените это на:

UserRole = false;
foreach(Role r in usersRole)
{
    if(r == item)
    {
        UserRole = true;
        break;
    }
}
0 голосов
/ 26 января 2011

Между этим и вашим предыдущим вопросом, думаю, я смогу понять, что вы пытаетесь сделать.

Прежде всего, если ваши пользователи могут иметь несколько ролей, вам нужно, чтобы перечисление ваших ролей было украшено атрибутом [Flags]. Я предполагаю, что это то, что вы хотите, так как вы используете флажки, а не радио-селектор.

Далее, чтобы динамически получить имена для Roles, вам нужно использовать что-то более похожее на [Enum.GetNames(enum)]. Если вы хотите что-то лучше для описания, чем имя значения в перечислении, вы можете довольно легко найти в Google функцию GetDescription, а затем применить атрибут [Description(...)] к каждому.

Вы также захотите написать функцию расширения enum.HasFlag(MyEnum.ValueToCheckAgainst) ( или использовать встроенную в .NET 4.0 ), чтобы определить, установлен флажок или нет.

Кроме того, ответ @ Shekhar_Pro также полезен, потому что вы хотите, чтобы ваша функция принимала только одну роль, а не массив из них для генерации списка UserRoleModel s. Затем вы вызовете эту функцию для каждого пользователя, которого хотите отобразить.

И последняя часть, превращая эти флажки обратно в значение Role, вам придется сделать это вручную. Напишите функцию, которая принимает массив из Role значений и их всех вместе (после того, как вы сделаете перечисление допустимых флагов). Тогда просто верните результат. Если вы хотите что-то более «элегантное», чем это, вы, вероятно, просто захотите сделать эту функцию расширением того, что, по вашему мнению, должно выводить эти значения (например, модель представления).

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