C# 如何使用LINQ Contains()查找枚举列表?

C# 如何使用LINQ Contains()查找枚举列表?,c#,.net,linq,contains,C#,.net,Linq,Contains,我有一个名为OrderStatus的枚举,它包含订单可以处于的各种状态: 创造 未决 等待 有效的 活跃的 加工 完成 我要做的是创建一个LINQ语句,它将告诉我OrderStatus是否有效、处于活动状态、是否已处理或已完成 现在我有一些类似于: var status in Order.Status.WHERE(status => status.OrderStatus == OrderStatus.Valid || status.OrderStatus =

我有一个名为
OrderStatus
的枚举,它包含订单可以处于的各种状态:

  • 创造
  • 未决
  • 等待
  • 有效的
  • 活跃的
  • 加工
  • 完成
我要做的是创建一个LINQ语句,它将告诉我OrderStatus是否有效、处于活动状态、是否已处理或已完成

现在我有一些类似于:

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

这是可行的,但很“冗长”。有没有办法将其转换为
Contains()
语句并将其缩短一点?

假设枚举是按照问题中指定的顺序定义的,可以使用整数比较来缩短它

var result = 
  Order.Status.Where(x => 
    (int)x >= (int)OrderStatus.Valid &
    & (int)x <= (int)OrderStatus.Completed);
var结果=
Order.Status.Where(x=>
(int)x>=(int)OrderStatus.Valid&
&(int)x当然:

您还可以在()
中定义一个扩展方法
,该方法将接受一个对象和一个参数数组,并基本上包装Contains函数:

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

请理解,并非所有Linq提供程序(如lambdas.NHibernate中的自定义扩展方法)在没有额外编码以扩展表达式解析器的情况下都无法正确转换in()函数,但Contains()工作正常。对于Linq 2对象,没有问题。

我使用了此扩展:

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

                     return list.Contains(value);           
    }

您可以将这些内容放在一个集合中,并使用:

OrderStatus searchStatus = new[] {
                OrderStatus.Valid,
                OrderStatus.Active,
                OrderStatus.Processed,
                OrderStatus.Completed };

var results = Order.Status.Where(status => searchStatus.Contains(status));

如果该组状态具有某种意义,例如,它们是接受订单的状态,则可以在枚举上定义扩展方法,并在linq查询中使用该扩展方法

public static class OrderStatusExtensions
{
    public static bool IsAccepted(this OrderStatuses status)
    {
        return status == OrderStatuses.Valid
            || status == OrderStatuses.Active
            || status == OrderStatuses.Processed
            || status == OrderStatuses.Completed;
    }
}

var acceptedOrders = from o in orders
                     where o.Status.IsAccepted()
                     select o;

即使你不能给这个方法一个简单的名字,你仍然可以使用像
IsValidThroughCompleted
这样的东西。在这两种情况下,它似乎以这种方式传达了更多的含义。

现在回答得不错,但以后可能会变得更脆弱。理解这段代码需要检查枚举以了解所有的代码定义的范围,并且开发人员必须始终能够定义一个连续的范围,精确地包含所需的代码(如果在“已处理”和“已完成”之间放置了一个用户不希望在结果中显示的常量,则此代码将中断)@KeithS,是的,我在回答的最后一段提到了这一点。是的,我同意,对我的应用程序来说有点太脆弱了,但是我真的很喜欢你这样做,因为它使代码更加灵活。我们可以轻松地添加一个新状态而不破坏代码。例如,扩展方法+1!我希望在as w中重构它以使用LINQ嗯,是的,我一直想这么做,但忘了:)是的,好主意。我也可以用类似的东西,很酷
   Where(x => x.IsIn(OrderStatus.Valid, ... )
OrderStatus searchStatus = new[] {
                OrderStatus.Valid,
                OrderStatus.Active,
                OrderStatus.Processed,
                OrderStatus.Completed };

var results = Order.Status.Where(status => searchStatus.Contains(status));
public static class OrderStatusExtensions
{
    public static bool IsAccepted(this OrderStatuses status)
    {
        return status == OrderStatuses.Valid
            || status == OrderStatuses.Active
            || status == OrderStatuses.Processed
            || status == OrderStatuses.Completed;
    }
}

var acceptedOrders = from o in orders
                     where o.Status.IsAccepted()
                     select o;