Итерация через перечисление в Silverlight?
В .Net можно выполнить итерацию по перечислению с помощью
System.Enum.GetNames(typeof(MyEnum))
или
System.Enum.GetValues(typeof(MyEnum))
Однако в Silverlight 3 Enum.GetNames и Enum.GetValues не определены. Кто-нибудь знает альтернативу?
Ответы
Ответ 1
Я понял, как это сделать, не делая предположений о перечислении, имитируя функции в .Net:
public static string[] GetNames(this Enum e) {
List<string> enumNames = new List<string>();
foreach (FieldInfo fi in e.GetType().GetFields(BindingFlags.Static | BindingFlags.Public)){
enumNames.Add(fi.Name);
}
return enumNames.ToArray<string>();
}
public static Array GetValues(this Enum e) {
List<int> enumValues = new List<int>();
foreach (FieldInfo fi in e.GetType().GetFields(BindingFlags.Static | BindingFlags.Public)) {
enumValues.Add((int)Enum.Parse(e.GetType(), fi.Name, false));
}
return enumValues.ToArray();
}
Ответ 2
Или, может быть, строго типизирован с использованием linq, например:
public static T[] GetEnumValues<T>()
{
var type = typeof(T);
if (!type.IsEnum)
throw new ArgumentException("Type '" + type.Name + "' is not an enum");
return (
from field in type.GetFields(BindingFlags.Public | BindingFlags.Static)
where field.IsLiteral
select (T)field.GetValue(null)
).ToArray();
}
public static string[] GetEnumStrings<T>()
{
var type = typeof(T);
if (!type.IsEnum)
throw new ArgumentException("Type '" + type.Name + "' is not an enum");
return (
from field in type.GetFields(BindingFlags.Public | BindingFlags.Static)
where field.IsLiteral
select field.Name
).ToArray();
}
Ответ 3
Я не пробовал это, но API-интерфейсы отражения должны работать.
Ответ 4
Я считаю, что это то же самое, что и в .NET Compact Framework. Если мы сделаем предположение, что ваши значения перечисления начинаются с 0 и используют каждое значение до тех пор, пока их диапазон не будет превышен, следующий код должен работать.
public static IList<int> GetEnumValues(Type oEnumType)
{
int iLoop = 0;
bool bDefined = true;
List<int> oList = new List<int>();
//Loop values
do
{
//Check if the value is defined
if (Enum.IsDefined(oEnumType, iLoop))
{
//Add item to the value list and increment
oList.Add(iLoop);
++iLoop;
}
else
{
//Set undefined
bDefined = false;
}
} while (bDefined);
//Return the list
return oList;
}
Очевидно, вы могли бы настроить код для возврата имен перечислений или для соответствия различным шаблонам, например. побитовые значения.
Ниже приведен альтернативный вариант метода, который возвращает IList<EnumType>
.
public static IList<T> GetEnumValues<T>()
{
Type oEnumType;
int iLoop = 0;
bool bDefined = true;
List<T> oList = new List<T>();
//Get the enum type
oEnumType = typeof(T);
//Check that we have an enum
if (oEnumType.IsEnum)
{
//Loop values
do
{
//Check if the value is defined
if (Enum.IsDefined(oEnumType, iLoop))
{
//Add item to the value list and increment
oList.Add((T) (object) iLoop);
++iLoop;
}
else
{
//Set undefined
bDefined = false;
}
} while (bDefined);
}
//Return the list
return oList;
}