简体   繁体   English

使用Enum.HasFlag()检查UInt16是否有标志?

[英]Checking UInt16 for flags using Enum.HasFlag()?

I have a C#/.NET 4.0 application that receives and parses some data from a network connection. 我有一个C#/。NET 4.0应用程序,该应用程序从网络连接接收并解析一些数据。 One particular piece of data that I need to parse is a UInt16 value that represents a set of flags. 我需要解析的一个特定数据是代表一组标志的UInt16值。 I've defined an enum that represents these flags like this: 我定义了一个枚举来表示这些标志,如下所示:

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

I going to try to use bitwise operators on this UInt16 value to determine which flags it indicated had been set. 我将尝试在此UInt16值上使用按位运算符,以确定它所指示的标志已被设置。 But then I ran across Enum.HasFlag() method and at first glance, that seemed like it would be easier than bitwise operations. 但是随后我遇到了Enum.HasFlag()方法,乍一看,这似乎比按位操作容易。 I've been trying to use the following method to determine which flags are set in the UInt16 value: 我一直在尝试使用以下方法来确定在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.");
        }
    }
}

This method obviously takes a parameter of type Fields (my enum) but I'm working with a UInt16 value that was sent to me. 该方法显然采用了类型为Fields的参数(我的枚举),但是我正在使用发送给我的UInt16值。 I assume that I need to convert the UInt16 into an instance of the Fields enum but I'm not sure how to do that. 我假设我需要将UInt16转换为Fields枚举的实例,但是我不确定该怎么做。 It doesn't seem to be as simple as just casting it (which doesn't give me an error but also doesn't return the expected results, either). 它似乎不像只是强制转换那样简单(它既不会给我带来错误,也不会返回预期的结果)。 Is it possible to do this using Enum.HasFlag() or should I just implement the bitwise operations and be done with it? 是否可以使用Enum.HasFlag()做到这一点,还是应该只实现按位操作并完成它?

I assume that I need to convert the UInt16 into an instance of the Fields enum but I'm not sure how to do that. 我假设我需要将UInt16转换为Fields枚举的实例,但是我不确定该怎么做。

That's easy - you need to cast to the underlying type of the enum, and then you can cast to the enum itself: 这很容易-您需要转换为枚举的基础类型,然后可以转换为枚举本身:

Fields value = (Fields) (int) incomingValue;

EDIT: As noted in comments, this check doesn't do what you want it to: 编辑:如注释中所述,此检查不会执行您想要的操作:

if (value.HasFlag(Fields.None))

From the documentation : 文档中

If the underlying value of flag is zero, the method returns true . 如果flag的基础值为零,则该方法返回true

Basically you want: 基本上你想要:

if (value == 0)

for that test instead. 代替该测试。

Maybe you want a Enum with UInt16 type? 也许您想要UInt16类型的枚举?

Declare your Enum using enum SomeFlag : UInt16 { } then casting your value to the enum directly, using (SomeFlag)someValue , will work. 使用enum SomeFlag : UInt16 { }声明您的枚举enum SomeFlag : UInt16 { }然后使用(SomeFlag)someValue将值直接转换为枚举将起作用。

And it's a good practice to add [Flags] attribute to your flag enum. 最好将[Flags]属性添加到您的标志枚举。 It doesn't really do something, but you can tell yourself and other viewers it's a flag, and debugger will show combined flags instead numeric value in watch panel. 它实际上并没有做任何事情,但是您可以告诉自己和其他查看者这是一个标志,并且调试器将在监视面板中显示组合标志而不是数字值。

问题在于,在您的第一个if中,您将您的值与0进行比较。HasFlag使用value的按位与和以及所传递的enum和bitwise以及任何值与0的结果为0的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM