Enum作为标志的问题

时间:2017-02-14 14:16:38

标签: c# enums bitwise-operators

我有以下enum

[Flags]
public enum Status { Nominal, Modified, DirOneOnly, DirTwoOnly, DirOneNewest, DirTwoNewest }

我试图查看Modified位是否已设置为true并尝试了以下方法:

if(_stateFlags.HasFlag(Status.Modified))
{
    //DoStuff
}   //Found out why this doesn't work after reading docs.

if((_stateFlags & Status.Modified) == Status.Modified)
{
    //DoStuff
}

后者是我进一步研究让我相信会起作用的方法。但是,当我_stateFlags = Status.DirTwoOnly时,上述陈述仍然似乎评估为true,这实在令我感到困惑。

我做了一些根本错误的事情吗?

3 个答案:

答案 0 :(得分:7)

你的问题有几个答案可以解释什么是错的。我建议完全采用不同的方法。

旗帜枚举对他们有90年代的感觉;如果你认为他们看起来像COM互操作那样,如果你认为COM枚举似乎是为了兼容20世纪70年代的比特代码,你就是对的。

我不会将此逻辑表达为新代码中的枚举。我会花时间编写一个清晰表达我实际语义的自定义结构。

struct Status
{
  public static readonly Status None = default(Status);
  private Status(int bits) { this.bits = bits; }
  private int bits;
  private const int NominalBitMask  = 0b0001;
  private const int ModifiedBitMask = 0b0010;
  ... etc ...
  public bool IsNominal => (this.bits & NominalBitMask) != 0;
  public Status WithNominal(bool f) => 
    new Status(f ? (this.bits | NominalBitMask) : (this.bits & ~NominalBitMask));
  ... etc ...

现在你可以使用它:

Status status = Status.None.WithNominal(true).WithModified(myFile.IsModified);
...
if (status.IsModified) ...

这是更多的工作吗?当然,预计大约需要20分钟的工作时间。但是你再也不会犯错误了。您有一个结构,您可以独立于使用它的逻辑进行测试。你的代码看起来像它的含义。你永远不必担心有人在你的枚举类型中输入一个整数并让它充满废话。您可以在您的类型中放置自定义逻辑;例如,假设存在三值标志 - 例如,true,false或null - 那些在标志枚举中很难做到,但您可以在自定义类型中轻松添加逻辑。等等。

答案 1 :(得分:6)

You need to define the enum constants as powers of two.

[Flags]
public enum Status
{
    Nominal = 1,
    Modified = 2,
    DirOneOnly = 4,
    DirTwoOnly = 8,
    DirOneNewest = 16,
    DirTwoNewest = 32
}

class Program
{
    static void Main(string[] args)
    {
        Status s = new Status();
        s |= Status.Modified;
        if (s.HasFlag(Status.Modified))
        {
            Console.WriteLine("Modified!");
        }
    }
}

答案 2 :(得分:1)

代码:

ExoPlayer

等于:

[Flags]
public enum Status { Nominal, Modified, DirOneOnly, DirTwoOnly, DirOneNewest, DirTwoNewest }

}

正如其他人所说,你需要使用2的幂来表示枚举值。