简体   繁体   English

迭代Flags Enum中的值 - 但保留顺序

[英]Iterate over values in Flags Enum - but keep the order

I have the following enum in my code: 我的代码中有以下enum

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

Now I have a method that can take a enum . 现在我有一个可以采用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. 我现在需要迭代值,但保持enum传递给方法的顺序。

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. 我找到了以下方法,它让我可以迭代它们,但遗憾的是它返回它在Enum本身中定义的Order而不是我如何调用该方法。 Iterate over values in Flags Enum? 迭代Flags Enum中的值?

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. ...此时你可能想要避免它成为一个标志枚举。

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. 考虑接受一个( params )非标志枚举值数组。

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 检查这样的东西是否适合你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM