使用Enum.HasFlag()检查UInt16的标志?

时间:2014-09-04 18:53:56

标签: c# enums bitflags

我有一个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()执行此操作,还是应该实现按位操作并完成它?

3 个答案:

答案 0 :(得分:3)

  

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

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

Fields value = (Fields) (int) incomingValue;

编辑:正如评论中所述,此检查并不是您想要的:

if (value.HasFlag(Fields.None))

来自documentation

  

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

基本上你想要:

if (value == 0)

代替该测试。

答案 1 :(得分:1)

也许您想要一个具有UInt16类型的枚举?

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

[Flags]属性添加到标记枚举中是一种很好的做法。它并没有真正做某事,但你可以告诉自己和其他观众它是一个标志,调试器将在监视面板中显示组合标志而不是数值。

答案 2 :(得分:0)

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