我对我的事情进行了枚举:
public enum Things
{
OneThing,
AnotherThing
}
我想为此枚举编写一个扩展方法(类似于Prise's answer here),但该方法适用于枚举的实例,ala
Things thing; var list = thing.ToSelectList();
我希望它能用于实际枚举:
var list = Things.ToSelectList();
我可以做到
var list = default(Things).ToSelectList();
但我不喜欢那种情况:)
我已经接近以下扩展方法了:
public static SelectList ToSelectList(this Type type)
{
if (type.IsEnum)
{
var values = from Enum e in Enum.GetValues(type)
select new { ID = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name");
}
else
{
return null;
}
}
像这样使用:
var list = typeof(Things).ToSelectList();
我们可以做得更好吗?
答案 0 :(得分:72)
扩展方法仅适用于实例,因此无法完成,但通过一些精心选择的类/方法名称和泛型,您可以生成看起来同样好的结果:
public class SelectList
{
// Normal SelectList properties/methods go here
public static SelectList Of<T>()
{
Type t = typeof(T);
if (t.IsEnum)
{
var values = from Enum e in Enum.GetValues(type)
select new { ID = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name");
}
return null;
}
}
然后你可以得到这样的选择列表:
var list = SelectList.Of<Things>();
IMO这比Things.ToSelectList()
读得好很多。
答案 1 :(得分:5)
没有
你能做的最好的就是把它放在一个静态类上,如下所示:
public static class ThingsUtils {
public static SelectList ToSelectList() { ... }
}
答案 2 :(得分:4)
Aaronaught的答案真的很棒,基于我做了以下实现:
public class SelectList
{
public static IEnumerable<Enum> Of<T>() where T : struct, IConvertible
{
Type t = typeof(T);
if (t.IsEnum)
{
return Enum.GetValues(t).Cast<Enum>();
}
throw new ArgumentException("<T> must be an enumerated type.");
}
}
在我看来,它有点安全,因为你可以 - 几乎 - 只用Enums调用它,当然,如果你想要一个无异常的版本,你可以简单地返回null。
答案 3 :(得分:1)
public static IQueryable GetAllEnumValues<T>()
{
IQueryable retVal = null;
Type targetType = typeof(T);
if(targetType.IsEnum)
{
retVal = Enum.GetValues(targetType).AsQueryable();
}
return retVal;
}
现在,您已从SelectList类中解除了此功能的耦合。因此,您可以在SelectList方法中或其他任何地方调用此方法。
public class SelectList
{
public static SelectList Of<T>
{
IQueryable enumValues = GetAllEnumValues<T>();
var values =
from Enum e in enumValues
select new { ID = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name");
}
}
答案 4 :(得分:1)
我使用'Type'代替'Enum'来添加扩展名。然后我可以从该方法返回任何类型的列表。这里返回字符串值:
public static string[] AllDescription(this Type enumType)
{
if (!enumType.IsEnum) return null;
var list = new List<string>();
var values = Enum.GetValues(enumType);
foreach (var item in values)
{
// add any combination of information to list here:
list.Add(string.Format("{0}", item));
//this one gets the values from the [Description] Attribute that I usually use to fill drop downs
//list.Add(((Enum) item).GetDescription());
}
return list.ToArray();
}
稍后我可以使用这种语法来获得我想要的东西:
var listOfThings = typeof (Things).AllDescription();
答案 5 :(得分:0)
在我看来,这是最干净的方式。为什么呢?
System.Enum
new
,这是一个小小的权衡(因为它必须有一个实例才能工作。null
,如果您尝试将其与其他类型一起使用,它就不会编译。用法:
(new Things()).ToSelectList()
扩展方法:
[Extension()]
public SelectList ToSelectList(System.Enum source)
{
var values = from Enum e in Enum.GetValues(source.GetType)
select new { ID = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name");
}
答案 6 :(得分:-1)
我认为,你最接近的就是把一些东西弄得像一个枚举而不是一个人。这就是我想出来的东西 - 虽然我确实理解了它的编程吸引力,但是在枚举中使用静态方法看起来似乎很多工作:
public class PseudoEnum
{
public const int FirstValue = 1;
private static PseudoEnum FirstValueObject = new PseudoEnum(1);
public const int SecondValue = 2;
private static PseudoEnum SecondValueObject = new PseudoEnum(2);
private int intValue;
// This prevents instantation; note that we cannot mark the class static
private PseudoEnum() {}
private PseudoEnum(int _intValue)
{
intValue = _intValue;
}
public static implicit operator int(PseudoEnum i)
{
return i.intValue;
}
public static implicit operator PseudoEnum(int i)
{
switch (i)
{
case FirstValue :
return FirstValueObject;
case SecondValue :
return SecondValueObject;
default:
throw new InvalidCastException();
}
}
public static void DoSomething(PseudoEnum pe)
{
switch (pe)
{
case PseudoEnum.FirstValue:
break;
case PseudoEnum.SecondValue:
break;
}
}
}