Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use LINQ Contains() to find a list of enums?

I have an enum called OrderStatus, and it contains various statuses that an Order can be in:

  • Created
  • Pending
  • Waiting
  • Valid
  • Active
  • Processed
  • Completed

What I want to do is create a LINQ statement that will tell me if the OrderStaus is Valid, Active, Processed or Completed.

Right now I have something like:

var status in Order.Status.WHERE(status => 
      status.OrderStatus == OrderStatus.Valid || 
      status.OrderStatus == OrderStatus.Active|| 
      status.OrderStatus == OrderStatus.Processed|| 
      status.OrderStatus == OrderStatus.Completed)

That works, but it's very "wordy". Is there a way to convert this to a Contains() statement and shorten it up a bit?

like image 951
Todd Davis Avatar asked Oct 27 '10 15:10

Todd Davis


People also ask

How do I find an enum list?

Get a list of Enum members. The idea is to use the Enum. GetValues() method to get an array of the enum constants' values. To get an IEnumerable<T> of all the values in the enum, call Cast<T>() on the array.

How are enums numbered?

Enum ValuesIf values are not assigned to enum members, then the compiler will assign integer values to each member starting with zero by default. The first member of an enum will be 0, and the value of each successive enum member is increased by 1. You can assign different values to enum member.

How do enums work in C#?

In the C# language, enum (also called enumeration) is a user-defined value type used to represent a list of named integer constants. It is created using the enum keyword inside a class, structure, or namespace. It improves a program's readability, maintainability and reduces complexity.


2 Answers

Sure:

var status in Order.Status.Where(status => new [] {
        OrderStatus.Valid, 
        OrderStatus.Active, 
        OrderStatus.Processed,
        OrderStatus.Completed
    }.Contains(status.OrderStatus));

You could also define an extension method In() that would accept an object and a params array, and basically wraps the Contains function:

public static bool In<T>(this T theObject, params T[] collection)
{
    return collection.Contains(theObject);
}

This allows you to specify the condition in a more SQL-ish way:

var status in Order.Status.Where(status => 
    status.OrderCode.In(
        OrderStatus.Valid, 
        OrderStatus.Active, 
        OrderStatus.Processed,
        OrderStatus.Completed));

Understand that not all Linq providers like custom extension methods in their lambdas. NHibernate, for instance, won't correctly translate the In() function without additional coding to extend the expression parser, but Contains() works just fine. For Linq 2 Objects, no problems.

like image 193
KeithS Avatar answered Oct 20 '22 18:10

KeithS


I have used this extension:

    public static bool IsIn<T>(this T value, params T[] list)
    {

                     return list.Contains(value);           
    }

You may use this as the condition:

   Where(x => x.IsIn(OrderStatus.Valid, ... )
like image 36
Aliostad Avatar answered Oct 20 '22 17:10

Aliostad