简体   繁体   中英

How to perform LINQ query over Enum?

Below is my Enumerator List :

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

I need to bind this to a Combobox , but, only show a few specific statuses and ignore the rest.

This is what I have so far:

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();
}

However, I feel that the code is little messy and is not a correct approach to bind filtered Enum list to a Combobox . Can anyone suggest a more robust way of doing this?

Update

I might need to change the Order of selection. So I need a generic solution which doesn't only get the first X number of statuses.

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

If you want to be able to change the list of items, just add them into a List<Activity.StatusEnum> and use 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));

Well if you're going to hard code the items that should be in the list anyway, why not just do this:

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

You could also dispose of the List<T> and just return the array itself. As long as you know these are the items you want, then there's no need for Linq.

Steps:

  • Get the enum values and cast the results to the type of the enum
  • Sort the enum values by their integer values (otherwise they sort naturally by unsigned magnitude)
  • Take the first 4

Code:

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

Output:

Open Rejected Accepted Started

First, if possible, I'd make your enum values powers of 2, so they could be OR'd together.

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

Then you could do something like this:

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 : In light of the fact that you can't change the enum values, I'd just recommend you use something like:

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

". . . only show the first 4 statuses and ignore the rest."

To get the first n elements of an IEnumerable<T> , use the Take method:

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

怎么样的东西:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM