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

本文关键字:UInt16 标志 检查 Enum HasFlag 使用 | 更新日期: 2023-09-27 18:20:51

我有一个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()来实现这一点,或者我应该只实现按位操作并使用它来完成?

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

我假设我需要将UInt16转换为Fields枚举的实例,但我不确定如何做到这一点。

这很容易——您需要转换为枚举的底层类型,然后可以转换为枚举本身:

Fields value = (Fields) (int) incomingValue;

编辑:正如评论中所指出的,这项检查并没有达到你想要的效果:

if (value.HasFlag(Fields.None))

来自文件:

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

基本上你想要:

if (value == 0)

取而代之的是测试。

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

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

[Flags]属性添加到您的标志枚举中是一种很好的做法。它并没有真正起到什么作用,但您可以告诉自己和其他查看者这是一个标志,调试器将在观察面板中显示组合标志,而不是数值。

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