29

申请的[Flags]真正作用是什么?

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


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

4

6 回答 6

29

来自MSDN 文章

有趣的是,当指定 Flags 时,Parse 和 Format 方法具有高级功能。

同样,Parse 方法可以成功地将逗号分隔的字符串解析为正确的数值。

于 2011-05-05T19:34:42.990 回答
17

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

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

问候

大卫

于 2011-05-05T19:54:09.767 回答
7

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

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

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

于 2011-05-05T19:22:40.587 回答
5

如果您问它在引擎盖下做了什么,据我所知,它会更改 ToString() 方法,仅此而已。

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

于 2011-05-05T19:23:21.167 回答
1

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

[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,但我只是确保这不是我使用枚举的情况。

于 2011-05-05T19:32:20.827 回答
0

Flags 提供了一个将枚举用于多个值的选项。

考虑一种情况,您希望在不同情况下使用复选框,但不想在数据库中创建不同的列。如果您有 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# 会追溯该编号以查找所有标记的内容。

于 2018-08-21T19:49:30.397 回答