有没有办法将类中的Enumerated属性设置为All available enums

本文关键字:设置 属性 All enums available Enumerated 有没有 | 更新日期: 2023-09-27 18:13:51

首先,我不知道这个问题的标题是什么——我甚至不知道如何陈述。

现在开始提问。让我们以System.IO.FileSystemWatcher类为例,在其中设置它的NotifyFilter属性:

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

设置单个属性需要相当多的代码。检查NotifyFilter,它是一个枚举。是否有一种">lazy"或">shortcut'的方法可以同时设置所有这些属性?我知道不一定需要它,但我的好奇心被激发了。

this.FileSystemWatcher1.NotifyFilter = <NotifyFilters.All>

有没有办法将类中的Enumerated属性设置为All available enums

,你总是可以做这样的事情

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;
}

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

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

All = ~0

如果枚举上应用了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"); 

编写一个通用实用程序来将c#枚举中的所有值屏蔽在一起,这比人们想象的要困难得多,因为

  1. 枚举的基础类型可以是byte、short、int或long;已签名或未签名
  2. 没有办法将对象直接转换为泛型枚举,可能是因为c#中没有内置枚举约束。必须先装箱,然后再取消装箱
  3. 所有的enum实用程序都是从c#1.0开始的,因此相当粗糙

这是我能做的最好的事情。我利用了以下内容:

  1. 将Int强制转换为C中的泛型枚举#
  2. C中的枚举类型约束#

这在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的建议简化更新