【问题标题】:Value is in enum list值在枚举列表中
【发布时间】:2011-07-16 06:57:07
【问题描述】:

我有一个相当基本的问题:如何检查给定值是否包含在枚举值列表中?

例如,我有这个枚举:

public enum UserStatus
{
    Unverified,
    Active,
    Removed,
    Suspended,
    Banned
}

现在我想检查status in (Unverified, Active)

我知道这行得通:

bool ok = status == UserStatus.Unverified || status == UserStatus.Active;

但是必须有一种更优雅的方式来编写它。

this question 的主题很相似,但都是处理 flags 枚举,而这不是 flags 枚举。

【问题讨论】:

  • status变量的数据类型是什么?
  • @Lav 变量status 的类型为UserStatus

标签: c# .net linq lambda enums


【解决方案1】:

这是一种在很多情况下都有很大帮助的扩展方法。

public static class Ext
{
    public static bool In<T>(this T val, params T[] values) where T : struct
    {
        return values.Contains(val);
    }
}

用法:

Console.WriteLine(1.In(2, 1, 3));
Console.WriteLine(1.In(2, 3));
Console.WriteLine(UserStatus.Active.In(UserStatus.Removed, UserStatus.Banned));

【讨论】:

  • 是的,这正是我想要的。同样,不知道为什么这不是内置的,但至少它是可能的。 :) 谢谢!
  • 这是一个非常好的方法!
  • 漂亮的代码...没想到扩展方法的this类型参数可以是泛型的。
  • .NET 4.0+ 有一个内置函数,Enum.HasFlag(Enum)。在此示例中,您可以像 bool ok = (UserStatus.Unverified | UserStatus.Active).HasFlag(status); 一样使用它。更多在这里,stackoverflow.com/a/61389498/4294275
  • 好的。对不起。非常基本的问题。这段代码应该属于哪里?
【解决方案2】:

如果是较长的枚举列表,可以使用:

var allowed = new List<UserStatus> { UserStatus.Unverified, UserStatus.Active };
bool ok = allowed.Contains(status);

否则无法绕过长的|| 谓词,检查每个允许的值。

【讨论】:

    【解决方案3】:

    使用Enum.IsDefined

    示例:

    public enum enStage {Work, Payment, Record, Return, Reject};
    int StageValue = 4;
    
    Enum.IsDefined(typeof(enStage), StageValue)
    

    【讨论】:

    • 看不到这是如何检查 5 个值中的 2 个的
    【解决方案4】:

    您可以在 .NET 4.0+ 中使用 Enum.HasFlag(Enum) 方法执行此操作,

    UserStatus status = UserStatus.Unverified; // just assumed status is Unverified
    
    bool ok = (UserStatus.Unverified | UserStatus.Active).HasFlag(status);
    

    你也可以通过赋值给一个变量来做同样的事情,

    UserStatus status = UserStatus.Active; // just assumed status is Active
    
    UserStatus unverifiedOrActive = UserStatus.Unverified | UserStatus.Active;
    
    bool ok = unverifiedOrActive.HasFlag(status);
    

    【讨论】:

    • 仅当枚举值实际上是标志(1、2、4、8、16、32、64,...)时才有效。
    【解决方案5】:
    UserStatus userStatus = null;
    Eum.TryParse<UserStatus>(status.ToString(), out userStatus);
    
    if(userStatus != null)
    {
      //it is not in the list
    }
    

    【讨论】:

    • 我认为这行不通,因为它会检查枚举中的每个值,而不是值的子集(如果我没看错的话)。
    • @Jerad 这行得通。试一试。我和Lav 发布的解决方案相同
    • @Avian - 但是您在哪里只检查未验证或活动值(与其他三个值相比)?
    • @Jerad。我的错。回答办公室的问题并没有给我太多时间阅读您的问题。
    • @Avian - 我明白,没问题。尽管如此,还是感谢您的尝试。
    【解决方案6】:

    为什么不创建一个方法来封装它?

    public bool UnVerifiedOrActive(User user)
    {
        return (user.UserStatus == UserStatus.Unverified || 
                user.UserStatus == UserStatus.Active);
    }
    

    【讨论】:

    • 谢谢,但这不是 DRY 的问题,更多的是简洁的代码。我仍然不确定为什么 C# 没有某种 in 运算符可用于此类情况。
    【解决方案7】:

    你可以试试关注

    UserStatus ustatus;
    if(Enum.TryParse<UserStatus>(c.ToString(), out ustatus))
    {
     ..Your logic
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      • 2010-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      相关资源
      最近更新 更多