使用标志作为三态参数

时间:2014-11-10 10:11:00

标签: c#

我想传递一个论据,说明"所有","有效"或"无效"。我认为我不会选择可空的布尔,而是给Flags一个机会。

由于我之前从未使用过它,我希望你能为我解答几个问题:

[Flags]
public enum Options
{
    Valid,
    Invalid
}

private void Foo(Options options)
{
    Debug.WriteLine(string.Format("valid: {0} {1}", 
    (options & Options.Valid) == Options.Valid, 
     options.HasFlag(Options.Valid)));

    Debug.WriteLine(string.Format("invalid: {0} {1}", 
    (options & Options.Invalid) == Options.Invalid, 
     options.HasFlag(Options.Invalid)));

    Debug.WriteLine("---");
}

protected void Page_Load(object sender, EventArgs e)
{
    Foo(Options.Valid | Options.Invalid);
    Foo(Options.Invalid);
    Foo(Options.Valid);
}

/*

Output:

valid: True True
invalid: True True
---
valid: True True
invalid: True True
---
valid: True True
invalid: False False

*/

正如您所看到的,这并没有给我想要的结果。我想知道的是,"有效","无效"或两个标志都已设置。我将如何实现这一目标?

1 个答案:

答案 0 :(得分:4)

对于标志,您必须分配值,以便布尔运算按预期工作:

[Flags]
public enum Options
{
    Valid = (1<<0), // 1
    Invalid = (1<<1), // 2
    All = Valid | Invalid
}

否则,系统会自动分配您的值,这会产生Valid=0Invalid=1

正如您所看到的,ValidInvalid被赋予2个值的幂(例如1,2,4,8 ......)。这是标志测试操作正常工作所必需的,因为它们依赖于简单的binary operations on the enum values

要检查是否设置了两个标志,请使用:

options.HasFlag(Options.Valid | Options.Invalid)

options.HasFlag(Options.All)