枚举肯定会令人困惑。我正在尝试在Enum类型上创建一个扩展方法,该方法将获取一个值并返回匹配的所有位的名称。
假设:
[Flags]
public enum PlanetsEnum
{
Mercury=1,
Venus=2,
Earth=4,
Mars=8,
Jupiter=16,
//etc....
}
我想创建一个只返回所选值的字典的扩展方法。所以如果:
PlanetsEnum neighbors = PlanetsEnum.Mars | PlanetEnum.Venus; //10
IDictionary dict = neighbors.ToDictionary();
foreach (KeyValuePair<String, Int32> kvp in dict)
{
Console.WriteLine(kvp.Key);
}
/*
* Should Print:
* Mars
* Venus
*/
我希望看到火星和火星金星写入控制台但我却看到了PlanetEnum的所有值。这是我的扩展方法代码:
public static IDictionary<string, Int32> ToDictionary(this Enum enumeration)
{
Type type = enumeration.GetType();
return Enum.GetValues(type).Cast<Int32>().ToDictionary(field => Enum.GetName(type, field));
}
有谁看到我做错了什么?我知道Enum.GetValues
正在返回枚举类型的所有字段,如何让它只返回枚举实例的字段?
非常感谢您的帮助,
基思
答案 0 :(得分:3)
这是您尝试做的LINQ-ified版本。您缺少的关键位是检查当前值:
public static IDictionary<string, int> ToDictionary(this Enum enumeration)
{
int value = (int)(object)enumeration;
return Enum.GetValues(enumeration.GetType()).OfType<int>().Where(v => (v & value) == value).ToDictionary(v => Enum.GetName(enumeration.GetType(), v));
}
修改强>
关于我们为什么要进行(int)(object)enumeration
演员的一点解释:
按位运算符仅对整数类型(如int)和布尔值起作用,但Enum不能直接转换为int。所以我们必须向下转换为一个对象并且推测它实际上表示一个int作为底层类型 - 编译器将允许我们将一个对象强制转换为int。如果枚举不是基于整数的,则会抛出运行时异常。
答案 1 :(得分:2)
尝试以下方法。它只适用于Enum的int32's
public static IDictionary<String, Int32> ToDictionary(this Enum enumeration)
{
var map = new Dictionary<string, int>();
var value = (int)(object)enumeration;
var type = enumeration.GetType();
foreach (int cur in Enum.GetValues(type))
{
if (0 != (cur & value))
{
map.Add(Enum.GetName(type, cur),cur);
}
}
return map;
}
答案 2 :(得分:1)
public enum CustomerType
{
Standard = 0,
Trade = 1
}
ddCustomerTypes.DataSource = (new Domain.CustomerType()).ToDictionary();
ddCustomerTypes.DataBind();
public static class EnumExtensionMethods
{
public static Dictionary<string, object> ToDictionary(this Enum enumeration)
{
Array names = Enum.GetNames(enumeration.GetType());
Dictionary<string, object> dictionary = new Dictionary<string, object>();
foreach (string name in names)
{
dictionary.Add(name, typeof(Domain.CustomerType).GetField(name).GetRawConstantValue() );
}
return dictionary;
}
public static List<KeyValuePair<string, object>> ToList(this Enum enumObject)
{
return enumObject.ToDictionary().ToList();
}
}