Как выполнить запрос 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 количество статусов.
Ответы
Ответ 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)