解析枚举扩展

时间:2014-03-01 22:10:14

标签: c#

我正在尝试创建一个Enum扩展来将其转换为某种对象:

var mods = RoleModel.Admin | RoleModel.Editor;

List<Role> rols = mods.Parse(x => new Role { Id = (Int32)x, Name = x.GetName() });

RoleModel可以是Enum或Flags Enum。我创建了以下扩展名:

public static T Parse<T>(this Enum value, Func<IEnumerable<Enum>, T> expression) where T : Object {

  Type type = value.GetType();

  IEnumerable<Enum> values;

  if (type.GetCustomAttributes<FlagsAttribute>().Any())
    values = Enum.GetValues(type).Cast<Enum>().Where(value.HasFlag);
  else 
    values = new List<Enum> { value };

  if (values == null)
    return default(T);

  return expression(values);      

} // Parse   

问题是x变成了IEnumerable而不是Enum。

如何使我的Parse方法类似于Select?

更新

我能够解决部分问题......我尝试了以下内容:

var a = RoleModel.Master;

var b = RoleModel.Master | RoleModel.Editor;

var c = a.Parse(x => new Role { Id = Convert.ToInt32(x) });

var d = b.Parse(x => new Role { Id = Convert.ToInt32(x) });

var e = new RoleModel().Parse(x => new Role { Id = Convert.ToInt32(x) });

在c和e上我无法使用(Int32)进行投射。我需要使用Convert。为什么?

在e我没有得到任何东西......我期待获得枚举的所有价值。为什么?

我目前的代码如下:

public static IEnumerable<T> Parse<T>(this Enum value, Func<Enum, T> expression) {

  Type type = value.GetType();

  IEnumerable<Enum> enumerations;

  if (type.GetCustomAttributes<FlagsAttribute>().Any())
    enumerations = Enum.GetValues(type).Cast<Enum>().Where(value.HasFlag);
  else 
    enumerations = new List<Enum> { value };

  foreach (Enum enumeration in enumerations)
    yield return expression(enumeration);      

} // Parse   

知道如何解决当前的问题吗?

谢谢你, 米格尔

2 个答案:

答案 0 :(得分:1)

实现这样的扩展:

public static IEnumerable<T> Parse<T>(this Enum value, Func<Enum, T> expression)
{

    Type type = value.GetType();

    IEnumerable<Enum> values;

    if (type.GetCustomAttributes(typeof(FlagsAttribute), false).Any())
        values = Enum.GetValues(type).Cast<Enum>().Where(value.HasFlag);
    else
        values = new List<Enum> { value };

    return values.Select(expression);

} // Parse 

并用作:

RoleModel model = RoleModel.Admin | RoleModel.Editor;

IEnumerable<Role> roles = model.Parse(x => new Role
                                            {
                                               Id = Convert.ToInt32(x),
                                               Name = Convert.ToString(x)
                                            }
                                     );

或没有转换:

IEnumerable<Role> roles = model.Parse(x => new Role
                                           {
                                               Id = (int)(RoleModel)x,
                                               Name = ((RoleModel)x).ToString()
                                           }
                                     );

On e I do not get anything ... I was expecting to get all values of the enum. Why? 要获得所有值,您可以做一些技巧:

[Flags]
enum RoleModel : byte
{Admin = 1, Editor = 2, User = 4, Viewer = 8};

然后使用:

var roles = ((RoleModel)byte.MaxValue()).Parse(x => ....

答案 1 :(得分:0)

这对你有用吗?它只是使用Enum作为参数声明函数并相应地调整主体:

public static List<T> Parse<T>(this Enum value, Func<Enum, T> expression) where T : Object {

   Type type = value.GetType();

  IEnumerable<Enum> values;

  if (type.GetCustomAttributes<FlagsAttribute>().Any())
    values = Enum.GetValues(type).Cast<Enum>().Where(value.HasFlag);
  else 
    values = new List<Enum> { value };

  if (values == null)
    return new List<T>(default(T));

  return values.Select(expression).ToList();

} // Parse