有没有办法将类中的枚举属性设置为所有可用的枚举?

时间:2014-07-20 20:53:17

标签: c# enums

首先,我不知道如何标题这个问题 - 我甚至混淆了如何陈述它。

现在提出问题。我们将System.IO.FileSystemWatcher类放在您设置NotifyFilter属性的位置:

            this.FileSystemWatcher1.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.FileName 
            | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security 
            | NotifyFilters.Size;

设置单个属性的代码相当多。检查NotifyFilter,这是一个枚举。是否有一个' lazy '或者' 快捷方式'一次设置所有这些属性的方法?我知道这不一定需要,但我的好奇心被激怒了。

this.FileSystemWatcher1.NotifyFilter = <NotifyFilters.All>

4 个答案:

答案 0 :(得分:13)

你总是可以这样做,

NotifyFilter ret = 0;
foreach(NotifyFilter v in Enum.GetValues(typeof(NotifyFilter)))
{
    ret |= v;   
}

不幸的是,我不知道更好的方法。但是你总是可以在通用的实用方法中抛出它。

private static T GetAll<T>() where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
       throw new NotSupportedException(); // You'd want something better here, of course.
    }

    long ret = 0; // you could determine the type with reflection, but it might be easier just to use multiple methods, depending on how often you tend to use it.
    foreach(long v in Enum.GetValues(typeof(T)))
    {
        ret |= v;
    }

    return (T)ret;
}

答案 1 :(得分:6)

没有编写自己的方法也没有办法 - 正如在其他地方正确回答的那样。

如果您的枚举是您的更改,则可以添加新值

All = ~0

答案 2 :(得分:3)

如果枚举上应用了Flags属性,则可以添加与所需枚举成员等效的数字,然后进行分配。

在你的问题的例子总结4 + 64 + 32 + 16 + 8 = 124然后你可以写

this.FileSystemWatcher1.NotifyFilter = (NotifyFilters) 124;

当然这会消除枚举的可读性并极大地导致维护问题,但正如你对我们的懒惰所说的那样:

public class Program
{
    [Flags]
    enum Enum:int
    {
        a = 1,
        b = 2
    }

    static void Main(string[] args)
    {
        Enum x = (Enum) 3;
        Console.WriteLine(x.ToString());

    }
}

输出:

a,b

更新:

我差点忘了。您当然可以将此字符串传递给Enum.Parse并获得所需的值:

this.FileSystemWatcher1.NotifyFilter = (NotifyFilter) Enum.Parse(typeof(NotifyFilter), 
"Attributes,CreationTime,FileName,LastAccess,LastWrite,Security,Size"); 

答案 3 :(得分:3)

编写一个通用实用程序来掩盖c#enum中的所有值,结果比人们想象的要困难得多,因为

  1. 枚举的基础类型可以是byte,short,int或long;签名或未签名。
  2. 无法将对象直接转换为通用枚举,也许是因为c#中没有内置的枚举约束。一个必须改为包装,然后取消装箱。
  3. 所有枚举实用程序的日期都是c#1.0,​​因此非常苛刻。
  4. 这是我能做的最好的事情。我使用了以下内容:

    1. Cast Int to Generic Enum in C#
    2. Enum type constraints in C#
    3. 在c ++ / CLI中这会更容易吗?

      /// <summary>
      /// Contains generic utilities for enums, constrained for enums only.
      /// </summary>
      public sealed class EnumHelper : Enums<Enum>
      {
          private EnumHelper()
          {
          }
      }
      
      /// <summary>
      /// For use by EnumHelper, not for direct use.
      /// </summary>
      public abstract class Enums<TEnumBase> where TEnumBase : class, IConvertible
      {
          private static void ThrowOnEnumWithoutFlags<TEnum>() where TEnum : struct, TEnumBase
          {
              var attributes = typeof(TEnum).GetCustomAttributes(typeof(FlagsAttribute), false);
              if (attributes.Length == 0)
              {
                  throw (new ArgumentException("The generic argument [<T>] must be an enumeration with the [FlagsAttribute] applied.", "T: " + typeof(TEnum).FullName));
              }
          }
      
          public static TEnum GetAll<TEnum>() where TEnum : struct, TEnumBase
          {
              ThrowOnEnumWithoutFlags<TEnum>();
              var underlyingType = Enum.GetUnderlyingType(typeof(TEnum));
              if (underlyingType == typeof(ulong))
              {
                  ulong value = 0;
                  foreach (var v in Enum.GetValues(typeof(TEnum)))
                      // Not sure I need the culture but Microsoft passes it in Enum.ToUInt64(Object value) - http://referencesource.microsoft.com/#mscorlib/system/enum.cs
                      value |= Convert.ToUInt64(v, CultureInfo.InvariantCulture); 
                  return (TEnum)Enum.ToObject(typeof(TEnum), value);
              }
              else
              {
                  long value = 0;
                  foreach (var v in Enum.GetValues(typeof(TEnum)))
                      // Not sure I need the culture but Microsoft passes it in Enum.ToUInt64(Object value) - http://referencesource.microsoft.com/#mscorlib/system/enum.cs
                      value |= Convert.ToInt64(v, CultureInfo.InvariantCulture);
                  return (TEnum)Enum.ToObject(typeof(TEnum), value);
              }
          }
      

      我测试了byte,sbyte,short,int,long,ushort,uint和ulong类型。

      根据hvd的建议,

      更新简化。