【问题标题】:Checking UInt16 for flags using Enum.HasFlag()?使用 Enum.HasFlag() 检查 UInt16 的标志?
【发布时间】:2014-09-05 04:27:46
【问题描述】:

我有一个 C#/.NET 4.0 应用程序,它接收和解析来自网络连接的一些数据。我需要解析的一个特定数据是表示一组标志的 UInt16 值。我已经定义了一个表示这些标志的枚举,如下所示:

public enum Fields
{
    None = 0,
    FirstFlag = 1,
    SecondFlag = 2,
    ThirdFlag = 4,
    FourthFlag = 8,
    FifthFlag = 16,
    SixthFlag = 32,
    SeventhFlag = 64,
    EighthFlag = 128
}

我将尝试对这个 UInt16 值使用按位运算符来确定它指示的哪些标志已设置。但后来我遇到了 Enum.HasFlag() 方法,乍一看,这似乎比按位运算更容易。我一直在尝试使用以下方法来确定 UInt16 值中设置了哪些标志:

public static void CheckForSetFields(Fields value)
{
    if (value.HasFlag(Fields.None))
    {
        System.Diagnostics.Debug.WriteLine("No fields are set!");
    }
    else
    {
        if (value.HasFlag(Fields.FirstFlag))
        {
            System.Diagnostics.Debug.WriteLine("First flag is set.");
        }
        if (value.HasFlag(Fields.SecondFlag))
        {
            System.Diagnostics.Debug.WriteLine("Second flag is set.");
        }

        // etc., etc.

        if (value.HasFlag(Fields.EighthFlag))
        {
            System.Diagnostics.Debug.WriteLine("Eighth flag is set.");
        }
    }
}

此方法显然采用 Fields 类型的参数(我的枚举),但我正在使用发送给我的 UInt16 值。我假设我需要将 UInt16 转换为 Fields 枚举的实例,但我不知道该怎么做。它似乎不像只是投射它那么简单(这不会给我一个错误,但也不会返回预期的结果)。是否可以使用 Enum.HasFlag() 来做到这一点,还是我应该只实现按位运算并完成它?

【问题讨论】:

  • 你的预期结果是什么?

标签: c# enums bitflags


【解决方案1】:

我假设我需要将 UInt16 转换为 Fields 枚举的实例,但我不知道该怎么做。

这很简单 - 您需要转换为枚举的基础类型,然后您可以转换为枚举本身:

Fields value = (Fields) (int) incomingValue;

编辑:如 cmets 中所述,此检查不会执行您想要的操作:

if (value.HasFlag(Fields.None))

来自documentation

如果 flag 的基础值为零,则该方法返回 true

基本上你想要的:

if (value == 0)

代替那个测试。

【讨论】:

  • 谢谢乔恩。我正在寻找一种快速的方法来测试所有可能的标志值组合,所以我在 for 循环中尝试了这个,incomingValue 为 0 到 Int16.MaxValue。循环的每次迭代都会调用 CheckForSetFields(value) ,这总是导致“未设置字段!”被写入调试输出。不应该有一些标志组合,其中 if (value.HasFlag(Fields.None)) 为假?希望这是有道理的。再次感谢您的回复。
  • @user685869:基本上HasFlag(Fields.None) 是不正确的 - 我会编辑我的答案来解释。
  • 感谢乔恩的额外解释!
【解决方案2】:

也许你想要一个 UInt16 类型的 Enum?

使用enum SomeFlag : UInt16 { } 声明您的枚举,然后使用(SomeFlag)someValue 直接将您的值转换为枚举,将起作用。

最好将[Flags] 属性添加到您的标志枚举中。它并没有真正做任何事情,但您可以告诉自己和其他查看者这是一个标志,并且调试器将在监视面板中显示组合标志而不是数值。

【讨论】:

    【解决方案3】:

    问题在于,在您的第一个 if 中,您将值与 0 进行比较。HasFlag 使用按位与值和传递的枚举和按位与任何值的结果,并且 0 为 0。所以你不会得到其他条件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-02
      • 2018-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多