2

I have the following enum in my code:

[Flags]
public enum Column
{
    FirstName = 1 << 0,
    LastName = 1 << 1,
    Address = 1 << 2,
}

Now I have a method that can take a enum.

public void ParseColumns(Column col)
{
    //do some parsing...
}

This method can be called like this:

ParseColumns(Column.FirstName | Column.LastName);
ParseColumns(Column.LastName);
ParseColumns(Column.LastName | Column.Address | Column.FirstName);
ParseColumns(Column.Address | Column.FirstName);

I now need to iterate through the values but keep the order in which the enum was passed to the methods.

I have found the following method which gave me the possibility to iterate through them, but sadly it returns the Order in which its defined in the Enum itself and not how I called the method. Iterate over values in Flags Enum?

Community
  • 1
  • 1
Rand Random
  • 7,300
  • 10
  • 40
  • 88
  • 2
    `Column.FirstName | Column.LastName` and `Column.LastName | Column.FirstName` are exactly the same value. What you're asking for is like making a call `Foo(1+1)` behave differently from `Foo(2)`. –  Oct 31 '14 at 14:07
  • `ParseColumns()` receive just one value (in your case it will be `int`), which obviously doesn't contains any *order* info. You will need to use suitable type which contains order (`List`, array, etc) or provide order information as another parameter (to example, `string` which consist of numbers, `"132"` would specify `FirstName` > `Address` > `LastName` order). – Sinatr Oct 31 '14 at 14:17

3 Answers3

8

I now need to iterate through the values but keep the order in which the enum was passed to the methods.

There's no such concept. The | operator doesn't have any way of preserving ordering. To put it another way, imagine we had:

public void Foo(int x)

and you called it with:

Foo(1 + 4)
Foo(2 + 3)

How would you expect it to differentiate? If you need to pass separate values in, with a specific preserved order, you should probably use:

public void ParseColumns(params Column[] columns)

... at which point you may want to avoid it being a flags enum at all.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
3

That is fundamentally impossible.

Flags enum values work by adding the values of the individual items (each of which are a single unique bit).

Addition is commutative, so you can't tell which order they were added in.

Consider accepting a (params) array of non-flags enum values.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

Its not possible, but an interesting but not very nice idea...

What you can do is combine an extension method (since operator overloading does not work) with bit shifts... Serialize then de-serialize the values... Still sounds like a bad idea, hahaha.

public static Column OR(this Column original, Column newc) {
    return (Column) ((int)original)| (((int) newc) << 3)
}
public static Column Get(this Column original) {
    // Some iterator that looks almost like the one you already have
}
public static Column GetOrder(this Column original) {
    // Some iterator that looks almost like the one you already have
}

then you can call this as follows

ParseColumns(Column.FirstName.OR(Column.LastName))

And then the implentation something like:

public void ParseColumns(Column col)
{
    col.Get();
    col.GetOrder();
}

Check if something like this will suit you

Barnstokkr
  • 2,904
  • 1
  • 19
  • 34