Reputation: 39354
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
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
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