使用标志作为三态参数

本文关键字:参数 标志 | 更新日期: 2023-09-27 18:29:47

我想传递一个表示"all"、"valid"或"invalid"的参数。与其使用可为null的bool,我想我应该给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
*/

正如你所看到的,这并没有给我想要的结果。我想知道的是,是否设置了"有效"、"无效"或两个标志。我该如何做到这一点?

使用标志作为三态参数

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

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

否则,您的值将被自动分配,这将导致Valid=0Invalid=1

正如你所看到的,ValidInvalid被分配了2的幂值(例如,1,2,4,8…)。这是标志测试操作正确工作所必需的,因为它们依赖于枚举值上的简单二进制操作。

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

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

options.HasFlag(Options.All)