【问题标题】:c# Get all enum values greater than a given value?c#获取所有大于给定值的枚举值?
【发布时间】:2011-10-12 01:52:41
【问题描述】:

我有以下成员角色枚举:

public enum RoleName
{
    RegisteredUser,
    Moderator,
    Administrator,
    Owner
}

我希望能够获取大于或等于给定角色的所有角色。

例如,我输入 Administrator,我得到一个带有 RoleName.AdministrationRoleName.Owner 的 IEnumerable

类似的东西:

public static void AddUserToRole(string username, RoleName level)
{
    var roles = Enum.GetValues(typeof(RoleName)).Cast<R>().ToList().Where(role => level > role);

    foreach (var role in roles)
    {
        Roles.AddUserToRole(username, role);
    }
}

【问题讨论】:

  • 考虑到 enum 默认是 INT 类型,将值与过滤器 int 进行比较还不够吗?

标签: c# enums


【解决方案1】:

可能取决于 .NET 的版本。但这对我来说效果很好:

无需转换或使用特殊技巧。只需与通常的运算符进行比较:

using System;

enum Test { a1, a2, a3, a4 }

class Program
{
    static void Main(string[] args)
    {
        Test a = Test.a2;

        Console.WriteLine((a > Test.a1));
        Console.WriteLine((a > Test.a2));
        Console.WriteLine((a > Test.a3));
        Console.WriteLine((a > Test.a4));

        Console.ReadKey();
    }
}

输出:

True
False
False
False

【讨论】:

    【解决方案2】:

    您可以使用以下辅助方法为您提供给定角色允许的一组角色:

        private IEnumerable<RoleName> AllAllowedRoles(RoleName level)
        {
            return Enum.GetValues(typeof(RoleName)).Cast<RoleName>().Where(role => level >= role);
        } 
    

    然后将它们全部分配给用户。

    【讨论】:

      【解决方案3】:

      为了有一个更好的定义哪个角色大于另一个你需要像这样为你的角色分配数值:

      public enum RoleName
      {
          RegisteredUser = 2,
          Moderator = 4,
          Administrator = 8,
          Owner = 16
      }
      

      现在,如果您将 RoleName 类型的任何实例转换为 (int),您将获得数值,因此您可以将它们相互比较。

      注意:
      1. 这里我使用 2 的幂作为值,以允许使用位运算符组合 RoleNames。

      【讨论】:

      • 错误;您不需要分配任何值。
      • 确实如此,但正如我所说:为了有一个“更好的定义”。否则你很容易混淆。但是通过给它们赋值,你总是可以快速判断。
      • 不确定在这里使用标志是个好主意。大多数组合是没有意义的,例如。所有者 |注册用户。
      【解决方案4】:

      这样做:

          public static void AddUserToRole(string username, RoleName level)
          {
              var roles = RolesLesserThanOrEqualTo(level);
      
              foreach (var role in roles)
              {
                  Roles.AddUserToRole(username, role.Name());
              }
          }
      
          public static IEnumerable<RoleName> RolesLesserThanOrEqualTo(RoleName level)
          {
              return Enum.GetValues(typeof(RoleName)).Cast<RoleName>().Where(role => level >= role);
          }
      

      【讨论】:

        【解决方案5】:

        您的代码完全正确,只是您需要Cast&lt;int&gt;() 而不需要ToList()

        【讨论】:

          【解决方案6】:
          public enum RoleName : int
          {
              RegisteredUser = 7,
              Moderator = 8,
              Administrator = 9,
              Owner = 10
          }
          
           public List<RoleName> GetGreaterOrEqual(RoleName role)
              {
                  List<RoleName> list = new List<RoleName>();
                  foreach (RoleName rn in Enum.GetValues(typeof(RoleName)))
                  {
                      if(rn >= role)
                          list.Add(rn);
                  }
                  return list;
              }
          

          你可以看看Can you loop through all enum values?

          【讨论】:

            【解决方案7】:

            您必须考虑枚举的基础类型。因此:

            static IEnumerable<T> Get<T>(T value) where T : struct {
                Type underlyingType = Enum.GetUnderlyingType(typeof(T));
                var compareToMethod = underlyingType.GetMethod(
                                          "CompareTo",
                                          new[] { underlyingType }
                                      );
                var values = Enum.GetValues(typeof(T));
                for (int index = 0; index < values.Length; index++) {
                    int comparison = (int)compareToMethod.Invoke(
                        Convert.ChangeType(value, underlyingType),
                        new object[] { values.GetValue(index) }
                    );
                    if (comparison >= 0) {
                        yield return (T)values.GetValue(index);
                    }
                 }
             }
            

            我不想想出一个好名字,但这很管用:

            var largerValues = Get<RoleName>(RoleName.Moderator);
            foreach(var largerValue in largerValues) {
                Console.WriteLine(largerValue);
            }
            

            【讨论】:

            • 反射真的是最好的方法吗?
            • @Nico:如果你希望它是通用的,是的。如果你只想要RoleName,不。
            猜你喜欢
            • 2010-11-03
            • 1970-01-01
            • 1970-01-01
            • 2010-09-17
            • 1970-01-01
            • 1970-01-01
            • 2021-07-25
            • 2011-04-18
            • 2011-10-20
            相关资源
            最近更新 更多