tags:

views:

514

answers:

5

Hi,
I have the following Enum:

Public Enum myEnum As Integer  
    first = &H1
    second = &H2
    third = &H4
    fourth = &H8
    fifth = &H10
    sixth = &H20
End Enum

It is neccessary, unfortunately, that the enum elements have those values, or at least have values that can be binary compared.

I have a class which can be set during construction to be one of two types, a type with values relating to first through fourth, and a second type with values relating to first through sixth.

I would like to use a For loop to iterate through 1-4 or 1-6 elements of the enum, but I have found that this code:

For enumType as myEnum = myEnum.first to myEnum.fourth
Next

iterates through {1,2,3,4,5,6,7,8} and not through {1,2,4,8}.
This is not ideal.

Obviously I can code around this issue, but I can see a scenario where that workaround could be easily missed in maintenance programming, and I'm hoping someone can recommend a simple solution that won't break if, for example, the values in the enum have to change at a later date.

+1  A: 

Look at Enum.GetValues(Type)

leppie
+2  A: 

Sorry for C#:

static IEnumerable<T> EnumRange<T>(T begin, T end)
{
    T[] values = (T[])Enum.GetValues(typeof(T));
    int beginIndex = Array.IndexOf(values, begin);
    int endIndex = Array.IndexOf(values, end);

    for(int i = beginIndex; i <= endIndex; ++i)
        yield return values[i];
}

foreach(MyEnum e in EnumRange(MyEnum.First, MyEnum.Fourth)
    // Code goes here
Anton Gogolev
Marked this as the answer over the others because I am bitter about VB *still* lacking the yield keyword.
Frosty840
A: 

I expect you'll need to use Enum.GetValues(), and filter the results to what you want. For example, using LINQ )(and using C#, as I don't know VB well enough):

(note: the important thing here is the GetValues - which should be identical between VB and C#)

static void Main() {
    var qry = from MyEnum value in Enum.GetValues(typeof(MyEnum))
              where value >= MyEnum.First && value <= MyEnum.Fourth
              orderby value // to sort by value; remove otherwise
              select value;

    foreach (var value in qry) {
        Console.WriteLine(value);
    }
}
enum MyEnum { 
    First = 0x01,
    Second = 0x02,
    Third = 0x04,
    Fourth = 0x08,
    Fifth = 0x10,
    Sixth = 0x20
}
Marc Gravell
A: 

Marc is basically right, except that you don't need to explicitly sort (Enum.GetValues already returns sorted), and you need to cast for output:

enum myEnum
{
    first = 0x1,
    second = 0x2,
    third = 0x4,
    fourth = 0x8,
    fifth = 0x10,
    sixth = 0x20,
}

public static void Main(string[] a)
{
    var qry = from myEnum value in Enum.GetValues(typeof(myEnum))
        where value >= myEnum.first && value <= myEnum.fourth
        select value;
    foreach(var value in qry)
    {
        Console.WriteLine((int)value);
    }
}
Matthew Flaschen
A: 

I know that this has already been answered, but it seems to me that this has been over thought. Why not do this?

    Private Shared Sub Main()

        Dim aryEnums As Array = [Enum].GetValues(GetType(myEnum))

        For i As Integer = 0 To aryEnums.GetLength(0) - 1

            Console.WriteLine(aryEnums(i))

        Next

    End Sub
Jim