tags:

views:

2057

answers:

5

In .Net it is possible to iterate through an enumeration by using

System.Enum.GetNames(typeof(MyEnum))

or

System.Enum.GetValues(typeof(MyEnum))

In Silverlight 3 however, Enum.GetNames and Enum.GetValues are not defined. Does anyone know an alternative?

A: 

I haven't tried this, but the reflection APIs should work.

John Fisher
A: 

I belive this is the same as in the .NET Compact Framework. If we make the assumption that your enum values start at 0 and use every value until their range is over the following code should work.

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;
}

Obviously you could tweak the code to return the enum names or to match diferent patterns e.g. bitwise values.

Stevo3000
+9  A: 

I figured out how to do this without making assumptions about the enum, mimicking the functions in .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();
}
eriksmith200
Good solution +1!
Stevo3000
I would however suggest that you return an IList<string> for the top method and an IList<int> for the second one. And remember that this will not support enums that represent a long value.
Stevo3000
+3  A: 

Or maybe strongly typed using linq, like this:

    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(type)).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();
    }
ptoinson
+1  A: 

Iterating over an enum is fundamental enough that we shouldn't have to write hacks. It's surprising that Microsoft didn't fix this in SL 4.

Brian