[Flags] 属性的真正作用是什么?

发布于 2024-11-05 08:10:26 字数 422 浏览 1 评论 0原文

应用 [Flags] 有何作用真的吗?

我知道它修改了 Enum.ToString,但是它还有其他作用吗? (例如不同的编译器或运行时行为等)


编辑:是的,我知道它记录了枚举旨在用作按位标志的事实,并且将其应用于位标志更符合逻辑。不过,我更多地询问的是具体的行为变化,而不是一般的编程实践。

What does applying [Flags] really do?

I know it modifies the behavior of Enum.ToString, but does it do anything else? (e.g. Different compiler or runtime behavior, etc.)


Edit: Yeah, I'm aware that it documents the fact that the enum is intended to be used as bitwise flags, and that it's more logical to apply it to bit flags. I was asking more about concrete behavior changes though, not general programming practices.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

城歌 2024-11-12 08:10:26

来自 MSDN 文章

有趣的是,当
指定标志、解析和格式
方法具有高级功能。

同样,Parse方法可以
成功解析逗号分隔的
像刚刚显示的字符串
正确的数值。

From an MSDN article:

It is interesting to note that when
Flags is specified, Parse and Format
methods feature advanced capabilities.

Likewise, the Parse method can
successfully parse a comma-separated
string like the one just shown into
the proper numeric value.

零度° 2024-11-12 08:10:26

请参阅此处 David M. Kean 的帖子。这似乎是一个语言互操作问题:

尽管 C# 很乐意允许用户在没有 FlagsAttribute 的情况下对枚举执行位操作,但 Visual Basic 却不允许。因此,如果您要将类型公开给其他语言,那么使用 FlagsAttribute 标记枚举是一个好主意;它还清楚地表明枚举的成员被设计为一起使用。

问候

大卫

See David M. Kean's post here. This appears to be a language interop issue:

Although C# happily allows users to perform bit operations on enums without the FlagsAttribute, Visual Basic does not. So if you are exposing types to other languages, then marking enums with the FlagsAttribute is a good idea; it also makes it clear that the members of the enum are designed to be used together.

Regards

David

街道布景 2024-11-12 08:10:26

以下是具体行为差异的列表:

  • 将 [flags] 的枚举设置为 None 将清除所有标志。
  • HasFlags 方法仅在存在此属性时才起作用。
  • 正如 Devio 所说,它改变了 Parse 和 Format 方法的功能。他链接到本文。显然它也会影响调试器中显示的内容。
  • 我认为 [flags] 可能会对 Web 服务中的代码生成产生影响,但 看来情况并非如此.
  • 需要明确的是,任何枚举都允许按位运算,无论是否带有[标志]。但使用它是最佳实践。

更多详细信息: http://msdn.microsoft.com/en-us/library/ ms229062.aspx

Here's a list of concrete behavioral differences:

  • Setting an enum with [flags] to None clears all the flags.
  • The HasFlags method only works when this attribute is present.
  • As Devio said, it changes the capabilities of the Parse and Format methods. He linked to this article. Apparently it also impacts that is shown in Debuggers.
  • I thought [flags] probably had an impact on code generation in webservices, but it appears that this is not the case.
  • To be clear, bitwise operations are allowed on any enumeration, with or without [flags]. But using it is the best practice.

More details: http://msdn.microsoft.com/en-us/library/ms229062.aspx

很酷不放纵 2024-11-12 08:10:26

如果你问它在幕后做了什么,据我所知,它会更改 ToString() 方法,仅此而已。

在 .Net 4 下,您可以使用 HasFlags 方法检查特定标志。如果我对 msdn 的解释正确,则必须使用 flags-attribute 才能使用此方法。但我还没有尝试过。

If you ask what it does under the hood, as far as I know, it changes the ToString() method, nothing other.

Under .Net 4 you have the HasFlags-method to check for specific flags. If I interpret msdn right, you have to use the flags-attribute for using this method. But I have not tried it.

在实践中,我使用的用途之一是指示多种状态。这是一些评估测试结果的代码的简化。测试可能是好的,也可能有多种原因导致不合格。这样做的好处是,我有一种方法可以评估测试的“正常性”,并且该方法能够通过一次返回来指示所有可能的失败条件。可能不是最好的设计,但在这种情况下它是有效的。

[Flags]
public enum ResultStatusEnum
{
    Ok = 0x1,
    SampleInvalid = 0x2,
    DirectionInvalid = 0x4,
    TestIsNotValid = 0x8
}

你可以这样设置:

ResultStatusEnum res = ResultStatusEnum.SampleInvalid | ResultStatusEnum.DirectionInvalid;

缺点是检查枚举的值变得很麻烦。这不会(必然)起作用:

res == ResultStatusEnum.Ok

您必须执行此操作来检查:

ResultStatusEnum.SampleInvalid == (res & ResultStatusEnum.SampleInvalid)

在这种情况下,拥有 ResultStatusEnum.Ok & 是不合逻辑的。 ResultStatusEnum.SampleInvalid,但我只是确保这不是我使用枚举的情况。

In practice, one of the uses I use is indicating multiple statuses. This is a simplification of some code that evaluates test results. The test can be Ok, or it could have several reasons for not being Ok. The advantage this gives, is I have one method that evaluates the tests "Ok-ness", and that method is able to indicate all the possible failure conditions with one return. May not be the best design, but it works in this case.

[Flags]
public enum ResultStatusEnum
{
    Ok = 0x1,
    SampleInvalid = 0x2,
    DirectionInvalid = 0x4,
    TestIsNotValid = 0x8
}

You set it like this:

ResultStatusEnum res = ResultStatusEnum.SampleInvalid | ResultStatusEnum.DirectionInvalid;

The disadvantage is that checking the values of the enum becomes cumbersome. This won't (necessarily) work:

res == ResultStatusEnum.Ok

You have to do this to check:

ResultStatusEnum.SampleInvalid == (res & ResultStatusEnum.SampleInvalid)

In this case, its illogical to have ResultStatusEnum.Ok & ResultStatusEnum.SampleInvalid, but I just make sure this isn't the case where I use the enum.

渔村楼浪 2024-11-12 08:10:26

标志提供了使用枚举来表示多个值的选项。

考虑这样一种情况,您想在不同情况下使用复选框,但不想在数据库中创建不同的列。如果您有 20 个复选框,则必须使用 bool 在数据库中创建 20 列。但通过标志,您可以创建一列并使用该值存储在该列中。在控制台中运行此示例以更好地理解它。

class Program
{
    static void Main(string[] args)
    {
        //Set the features that you require for car. Consider it as checked in the UI.
        CarFeatures carFeatures = CarFeatures.AC | CarFeatures.Autopilot| CarFeatures.Sunroof;

        //Do the backend logic
        if (carFeatures.HasFlag(CarFeatures.Autopilot))
        {
            //Show Autopilot cars
        }
        //See the what carfeatures are required
        Console.WriteLine(carFeatures);
        //See the integer value of the carfeatures
        Console.WriteLine((int)carFeatures);
        Console.ReadLine();
    }
}

[Flags]
public enum CarFeatures
{
    AC=1,
    HeatedSeats= 2,
    Sunroof= 4,
    Autopilot= 8,
}

不同的组合总是会给你一个唯一的数字,c# 可以跟踪该数字来查找所有标记的内容。

Flags gives an option to use enum for multiple value.

Consider a situation where you want to use Checkboxes for different situation but you do not want to create different columns in the database. If you have 20 check boxes you will have to create 20 columns in the database with bool. But with flags you can create one column and use that value to store in the column. Run this example in the console to understand it better.

class Program
{
    static void Main(string[] args)
    {
        //Set the features that you require for car. Consider it as checked in the UI.
        CarFeatures carFeatures = CarFeatures.AC | CarFeatures.Autopilot| CarFeatures.Sunroof;

        //Do the backend logic
        if (carFeatures.HasFlag(CarFeatures.Autopilot))
        {
            //Show Autopilot cars
        }
        //See the what carfeatures are required
        Console.WriteLine(carFeatures);
        //See the integer value of the carfeatures
        Console.WriteLine((int)carFeatures);
        Console.ReadLine();
    }
}

[Flags]
public enum CarFeatures
{
    AC=1,
    HeatedSeats= 2,
    Sunroof= 4,
    Autopilot= 8,
}

The different combination always gives you a unique number which c# tracks back to find what all are marked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文