簡體   English   中英

用枚舉作為標志的問題

[英]Problems with Enum as Flags

我有以下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 ,這真讓我感到困惑。

我是從根本上做錯了嗎?

您對問題有幾個答案,可以解釋出什么問題。 我建議完全采用其他方法。

標記枚舉對他們有1990年代的感覺。 如果您認為它們看起來像是用於COM互操作的,並且您認為COM枚舉看起來是為了與1970年代的位糾纏代碼兼容,那么您是對的。

我不會將此邏輯表示為新代碼中的枚舉。 我會花時間編寫一個清晰表達我實際語義的自定義結構。

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) ...

還有更多工作嗎? 當然,還有大約二十分鍾的工作要做。 但是,您再也不會犯任何糾纏不清的錯誤了。 您擁有一個可以獨立於使用它的邏輯進行測試的結構。 您的代碼看起來像是什么意思。 您永遠不必擔心有人將整數轉換為您的枚舉類型並使其毫無意義。 您可以在類型中添加自定義邏輯; 例如,假設存在三值標志(例如,true,false或null),這在標志枚舉中很難做到,但是您可以輕松地在自定義類型中添加邏輯。 等等。

您需要將枚舉常量定義為2的冪。

[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!");
        }
    }
}

編碼:

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

等於:

[Flags]
public enum Status
{ 
    Nominal      = 0,  // in bits: ... 0000 0000
    Modified     = 1,  //              0000 0001
    DirOneOnly   = 2,  //              0000 0010
    DirTwoOnly   = 3,  //              0000 0011 **common bit with Modified state **
    DirOneNewest = 4,
    DirTwoNewest = 5,

}

因此,正如其他人所說,枚舉值需要使用2的冪。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM