Generic enum constraint
I have inherited a web api that has lots of enums defined in code, I want to convert them to a view-model class called EnumView so they can be serialized as below...
{Id: value, Name: enumName}
public class EnumView
{
public int Id { get; set; }
public string Name { get; set; }
}
Upon restricting the Generic class to the enum type, I get the warning
Constraint cannot be special class 'System.Enum'
This is the generic converter that I was going to use...
public class EnumViewConverter<T> where T : Enum
{
public static List<EnumView> ConvertToView()
{
List<EnumView> enumViews = new List<EnumView>();
T[] enumValues = (T[])Enum.GetValues(typeof(T));
foreach (var enumValue in enumValues)
{
var enumView = new EnumView
{
Id = (int)enumValue,
Name = Enum.GetName(typeof(T), enumValue)
};
enumViews.Add(enumView);
}
return enumViews;
}
}
Without T being constrained to an enum, the following conversion doesn't compile...
Id = (int)enumValue,
Due to the issue around a lack of generic enum constraints, what's the best way to go about this?
You could use : Id = Convert.ToInt32(enumValue) instead of the casting (int)
And if you want to add some 'constraint' to check the type at the compilation you could set 'where T : struct' it will at least prevent to set class type.
In the end I used...
public static class EnumViewConverter<T> where T : struct
{
public static List<EnumView> ConvertToView()
{
if (!typeof(T).IsEnum) throw new ArgumentException("T must be an enumerated type");
List<EnumView> enumViews = new List<EnumView>();
T[] enumValues = (T[])Enum.GetValues(typeof(T));
foreach (var enumValue in enumValues)
{
var enumView = new EnumView
{
Id = Convert.ToInt32(enumValue),
Name = Enum.GetName(typeof(T), enumValue)
};
enumViews.Add(enumView);
}
return enumViews;
}
}
Called by...
var views = EnumViewConverter<FooBarEnum>.ConvertToView();
Thanks for all the help, could have sworn I tried this earlier:(
To expand on my earlier comment, the technique described in this answer uses a nested class with a generic parameter dependent on its parent class to emulate generic Enum
constraints. You could use this approach here:
public abstract class ConverterClassUtils<TClass>
where TClass : class
{
public class ViewConverter<TInner> where TInner : struct, TClass
{
public static List<EnumView> ConvertToView()
{
List<EnumView> enumViews = new List<EnumView>();
TInner[] enumValues = (TInner[])Enum.GetValues(typeof(TInner));
foreach (var enumValue in enumValues)
{
var enumView = new EnumView
{
Id = (int)(object)enumValue,
Name = Enum.GetName(typeof(TInner), enumValue)
};
enumViews.Add(enumView);
}
return enumViews;
}
}
}
public class EnumConverter : ConverterClassUtils<Enum> { }
then the following compiles:
var view = EnumConverter.ViewConverter<SomeEnum>.ConvertToView();
while this does not:
var view = EnumConverter.ViewConverter<int>.ConvertToView();
链接地址: http://www.djcxy.com/p/54422.html
上一篇: Swift中的泛型枚举
下一篇: 泛型枚举约束