Подтвердить что ты не робот

Как выполнить запрос LINQ над Enum?

Ниже мой Enumerator List:

public enum StatusEnum
{
    Open = 1,
    Rejected = 2,
    Accepted = 3,
    Started = 4,
    Completed = 5,
    Cancelled = 6,
    Assigned = 7
}

Мне нужно привязать это к Combobox, но показывать только несколько определенных статусов и игнорировать остальные.

Это то, что у меня есть до сих пор:

public static List<Activity.StatusEnum> StatusList()
{
        IEnumerable<Activity.StatusEnum> query = Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>()
                        .Where(x => x == Activity.StatusEnum.Open
                            || x == Activity.StatusEnum.Rejected
                            || x == Activity.StatusEnum.Accepted
                            || x == Activity.StatusEnum.Started);
        return query.ToList();
}

Однако я чувствую, что код немного беспорядочен и не является правильным подходом к привязке отфильтрованного списка Enum к Combobox. Может ли кто-нибудь предложить более надежный способ сделать это?

Update

Мне может потребоваться изменить порядок выбора. Поэтому мне нужно общее решение, которое не только получает первое X количество статусов.

4b9b3361

Ответ 1

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

public static List<Activity.StatusEnum> StatusList()
{
    return new List<Activity.StatusEnum>
    { 
        Activity.StatusEnum.Open, 
        Activity.StatusEnum.Rejected, 
        Activity.StatusEnum.Accepted, 
        Activity.StatusEnum.Started 
    };
}

Вы также можете избавиться от List<T> и просто вернуть массив. Пока вы знаете, что это те предметы, которые вам нужны, тогда нет необходимости в Linq.

Ответ 2

return Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>().Where((n, x) => x < 4);

Если вы хотите изменить список элементов, просто добавьте их в List<Activity.StatusEnum> и используйте Contains:

var listValid = new List<Activity.StatusEnum>() { Activity.StatusEnum.Open, Activity.StatusEnum.Rejected, Activity.StatusEnum.Accepted, Activity.StatusEnum.Started };
return Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>().Where(n => listValid.Contains(n));

Ответ 3

Во-первых, если возможно, я сделаю ваши значения enum равными 2, поэтому они могут быть OR'd вместе.

public enum StatusEnum
{
    Open = 1,
    Rejected = 2,
    Accepted = 4,
    Started = 8,
    Completed = 16,
    Cancelled = 32,
    Assigned = 64
}

Тогда вы можете сделать что-то вроде этого:

public static List<Activity.StatusEnum> StatusList()
{
    var statusesToShow = Activity.StatusEnum.Open | Activity.StatusEnum.Rejected | Activity.StatusEnum.Accepted | Activity.StatusEnum.Started;

    return Enum
        .GetValues(typeof(Activity.StatusEnum))
        .Cast<Activity.StatusEnum>()
        .Where(x => (x & statusesToShow) == x)
        .ToList();
}

EDIT. Ввиду того, что вы не можете изменить значения перечисления, я бы просто рекомендовал вам использовать что-то вроде:

public static List<Activity.StatusEnum> StatusList()
{
    return new List<Activity.StatusEnum> {
        Activity.StatusEnum.Open, 
        Activity.StatusEnum.Rejected, 
        Activity.StatusEnum.Accepted, 
        Activity.StatusEnum.Started
    };
}

Ответ 4

"... показывать только первые 4 состояния и игнорировать остальные."

Чтобы получить первые n элементы IEnumerable<T>, используйте метод Take:

return Enum.GetValues(typeof(Activity.StatusEnum))
    .Cast<Activity.StatusEnum>()
    .Take(4)
    .ToList();

Ответ 5

return Enum.GetValues(typeof(Activity.StatusEnum))
.Cast<Activity.StatusEnum>()
.OrderBy(se =>(int)se)
.Take(4);

Я нахожу LINQPad бесценным для таких вещей. Это то, что у меня есть в LINQPad с "Language", установленным в "С# Program":

void Main()
{
    Activity.StatusList().Dump();
    Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>().OrderBy(se =>(int)se).Take(4).Dump();
}

// Define other methods and classes here
public static class Activity {
public enum StatusEnum
{
    Open = 1,
    Rejected = 10, // changed to 10 for testing
    Accepted = 3,
    Started = 4,
    Completed = 5,
    Cancelled = 6,
    Assigned = 7,
}

public static List<StatusEnum> StatusList()
{
        IEnumerable<Activity.StatusEnum> query = Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>()
                        .Where(x => x == Activity.StatusEnum.Open
                            || x == Activity.StatusEnum.Rejected
                            || x == Activity.StatusEnum.Accepted
                            || x == Activity.StatusEnum.Started);
        return query.ToList();
}

}

Ответ 6

Как насчет чего-то по строкам:

.Where(x => x <= Activity.StatusEnum.Started)