C# 如何将整数标记为枚举的通用列表?

C# 如何将整数标记为枚举的通用列表?,c#,generics,enums,enum-flags,C#,Generics,Enums,Enum Flags,我一直在为我的问题寻找解决办法,但到目前为止,我还没有找到解决办法 我需要获取由int值标记的enum的值列表。 我可以在特定情况下执行此操作,但我想为泛型枚举器创建一个泛型函数 具体案例的代码为: IList<MyEnum> EnumList= new List<MyEnum>(); MyEnum EnumIUseToFlag= (MyEnum)intToParse; foreach (MyEnumitem in Enu

我一直在为我的问题寻找解决办法,但到目前为止,我还没有找到解决办法

我需要获取由
int
值标记的
enum
的值列表。
我可以在特定情况下执行此操作,但我想为泛型枚举器创建一个泛型函数

具体案例的代码为:

        IList<MyEnum> EnumList= new List<MyEnum>();
        MyEnum EnumIUseToFlag= (MyEnum)intToParse;

        foreach (MyEnumitem in Enum.GetValues(typeof(MyEnum)))
        {
            if (EnumIUseToFlag.HasFlag(item))
            {
                EnumList.Add(item);
            }
        }
IList EnumList=new List();
MyEnumiuSetOfLag=(MyEnumum)intToParse;
foreach(Enum.GetValues中的MyEnumitem(typeof(MyEnum)))
{
if(EnumIUseToFlag.HasFlag(项目))
{
枚举列表。添加(项);
}
}
现在,对于通用方法,我尝试了以下方法:

    public static IList<T> GetFlaggedValues<T>(int intValue) where T : struct, IConvertible
    {

        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("T must be an enumerated type");
        }

        IList<T> listToReturn = new List<T>();
        Enum enumToParse = Enum.Parse(typeof(T), intValue.ToString()) as Enum;
        foreach (T item in Enum.GetValues(typeof(T)))
        {
            // here I am not able to cast item in the integer
            //values i need to use in order to flag my enum

        }

        return listToReturn;
    }
公共静态IList GetFlaggedValue(int intValue),其中T:struct,IConvertible
{
if(!typeof(T).IsEnum)
{
抛出新ArgumentException(“T必须是枚举类型”);
}
IList listToReturn=新列表();
Enum enumToParse=Enum.Parse(typeof(T),intValue.ToString())作为Enum;
foreach(Enum.GetValues中的T项(typeof(T)))
{
//在这里,我无法在整数中强制转换项
//标记枚举所需使用的值
}
返回列表返回;
}
简单的答案是——不要使用泛型。这个问题不需要。使用良好的旧继承并将标志作为
System.Enum
传递,它是所有枚举的基类

public static IList<Enum> GetFlaggedValues(Enum flag) 
{
    return Enum
        .GetValues(flag.GetType())
        .Cast<Enum>()
        .Where(e => e.HasFlag(flag))
        .ToList();
}
输出:

Blue
Green
Purple
由于我们使用
Enum
基类型的方式,不可能使用非Enum参数调用此方法,因此无需进行混乱的验证检查并引发异常。c#中的泛型无法做到这一点

另一方面,返回类型是
List
,而不是
List
,这可能真的让您感到困扰。好的如果您坚持为resultset创建强类型列表,您可以来回转换,如下所示:

public static IList<T> GetFlaggedValues<T>(T input) where T : struct, IConvertible
{
    Enum flag = input as Enum;
    if (flag == null) return new List<T>();
    return Enum
        .GetValues(typeof(T))
        .Cast<Enum>()
        .Where(e => e.HasFlag(flag))
        .Cast<T>()
        .ToList();
}
var list = GetFlaggedValues((MyEnum)0xF0F);
不用打字

var list = GetFlaggedValues<MyEnum>((int)MyEnum.Blue);  //Ugly
…编译器将推断

关于

的完整代码简单的答案是——不要使用泛型。这个问题不需要。使用良好的旧继承并将标志作为
System.Enum
传递,它是所有枚举的基类

public static IList<Enum> GetFlaggedValues(Enum flag) 
{
    return Enum
        .GetValues(flag.GetType())
        .Cast<Enum>()
        .Where(e => e.HasFlag(flag))
        .ToList();
}
输出:

Blue
Green
Purple
由于我们使用
Enum
基类型的方式,不可能使用非Enum参数调用此方法,因此无需进行混乱的验证检查并引发异常。c#中的泛型无法做到这一点

另一方面,返回类型是
List
,而不是
List
,这可能真的让您感到困扰。好的如果您坚持为resultset创建强类型列表,您可以来回转换,如下所示:

public static IList<T> GetFlaggedValues<T>(T input) where T : struct, IConvertible
{
    Enum flag = input as Enum;
    if (flag == null) return new List<T>();
    return Enum
        .GetValues(typeof(T))
        .Cast<Enum>()
        .Where(e => e.HasFlag(flag))
        .Cast<T>()
        .ToList();
}
var list = GetFlaggedValues((MyEnum)0xF0F);
不用打字

var list = GetFlaggedValues<MyEnum>((int)MyEnum.Blue);  //Ugly
…编译器将推断


关于

的完整代码这将适用于您:

    public static IList<T> GetFlaggedValues<T>(ulong intValue) where T : struct
    {
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("T must be an enumerated type");
        }
        var flagAttrib = Attribute.GetCustomAttribute(typeof(T), typeof(FlagsAttribute));
        if(flagAttrib==null)
        {
            throw new ArgumentException("T must have [Flags] attribute.");
        }

        List<T> vals = new List<T>();
        foreach (var e in Enum.GetValues(typeof(T)))
        {
            var item = Convert.ToUInt64(e);
            if ((item & intValue) != 0)
                vals.Add((T)Enum.ToObject(typeof(T), item));
        }
        return vals;
    }
公共静态IList GetFlaggedValue(ulong intValue),其中T:struct
{
if(!typeof(T).IsEnum)
{
抛出新ArgumentException(“T必须是枚举类型”);
}
var flagAttrib=Attribute.GetCustomAttribute(typeof(T),typeof(FlagsAttribute));
如果(flagAttrib==null)
{
抛出新的ArgumentException(“T必须具有[Flags]属性。”);
}
List VAL=新列表();
foreach(Enum.GetValues中的变量e(typeof(T)))
{
var项目=Convert.ToUInt64(e);
如果((项目和intValue)!=0)
VAL.Add((T)Enum.ToObject(typeof(T),item));
}
返回VAL;
}

这将适用于您:

    public static IList<T> GetFlaggedValues<T>(ulong intValue) where T : struct
    {
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("T must be an enumerated type");
        }
        var flagAttrib = Attribute.GetCustomAttribute(typeof(T), typeof(FlagsAttribute));
        if(flagAttrib==null)
        {
            throw new ArgumentException("T must have [Flags] attribute.");
        }

        List<T> vals = new List<T>();
        foreach (var e in Enum.GetValues(typeof(T)))
        {
            var item = Convert.ToUInt64(e);
            if ((item & intValue) != 0)
                vals.Add((T)Enum.ToObject(typeof(T), item));
        }
        return vals;
    }
公共静态IList GetFlaggedValue(ulong intValue),其中T:struct
{
if(!typeof(T).IsEnum)
{
抛出新ArgumentException(“T必须是枚举类型”);
}
var flagAttrib=Attribute.GetCustomAttribute(typeof(T),typeof(FlagsAttribute));
如果(flagAttrib==null)
{
抛出新的ArgumentException(“T必须具有[Flags]属性。”);
}
List VAL=新列表();
foreach(Enum.GetValues中的变量e(typeof(T)))
{
var项目=Convert.ToUInt64(e);
如果((项目和intValue)!=0)
VAL.Add((T)Enum.ToObject(typeof(T),item));
}
返回VAL;
}

在foreach中,您只需添加下一行即可:

        var itemAsEnumValue = (Enum)Enum.Parse(typeof(T), item.ToString());

        if (enumToParse.HasFlag(itemAsEnumValue))
        {
            listToReturn.Add(item);
        }

在foreach中,您只需添加下一行:

        var itemAsEnumValue = (Enum)Enum.Parse(typeof(T), item.ToString());

        if (enumToParse.HasFlag(itemAsEnumValue))
        {
            listToReturn.Add(item);
        }