Miguel Moura
Miguel Moura

Reputation: 39354

Parse Enum Extension

I am trying to create an Enum extension to convert it to some kind of object:

var mods = RoleModel.Admin | RoleModel.Editor;

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

The RoleModel can be an Enum or a Flags Enum. I created the following extension:

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   

The problem is that x becomes an IEnumerable instead of an Enum.

How can I make my Parse method similar to a Select?

UPDATE

I was able to fix part of the problems ... I tried the following:

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

On c and e I am not able to cast using (Int32). I need to use Convert. Why?

On e I do not get anything ... I was expecting to get all values of the enum. Why?

My current code is the following:

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   

Any idea how to solve the current problems?

Thank You, Miguel

Upvotes: 0

Views: 212

Answers (2)

Hamlet Hakobyan
Hamlet Hakobyan

Reputation: 33381

Implement extension like this:

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 

and use as:

RoleModel model = RoleModel.Admin | RoleModel.Editor;

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

or without convert:

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? To get all values you can do some trick like:

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

then use:

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

Upvotes: 1

G&#225;bor Bakos
G&#225;bor Bakos

Reputation: 9100

Would this work for you? It just declares the function with the Enum as parameter and adjusted the body accordingly:

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   

Upvotes: 0

Related Questions