C# BCL中是否有(隐藏良好的)通用枚举用于启用/禁用?

C# BCL中是否有(隐藏良好的)通用枚举用于启用/禁用?,c#,.net,enums,C#,.net,Enums,所以,我只是讨厌使用true/false作为“enabled”/“disabled”的方法参数。自由地引用杰夫的话:“我从根本上不喜欢它” 我反复发现自己在各地不同的名称空间中为每个新项目定义了自己的枚举,如下所示: public enum Clickability { Disabled, Enabled } public enum Editability { Disabled, Enabled } public enum Serializability {

所以,我只是讨厌使用
true
/
false
作为“enabled”/“disabled”的方法参数。自由地引用杰夫的话:“我从根本上不喜欢它”

我反复发现自己在各地不同的名称空间中为每个新项目定义了自己的枚举,如下所示:

public enum Clickability
{
    Disabled,
    Enabled
}

public enum Editability
{
    Disabled,
    Enabled
}

public enum Serializability
{
    Disabled,
    Enabled
}

是否有一个通用枚举可用于这些场景?

否,BCL中没有此类枚举(据我所知)。但是,不难从你反复创建的其中一个中选取一个,并使其更加通用:

public enum Ability
{
    Disabled,
    Enabled
}

将它放入一些具有类似常规内容的类库中,并在您的项目中重用它。

问题在于,在真正有问题的情况下,当存在多个参数且不清楚“标志”控制的是什么时,它实际上没有帮助

如果您遵循“避免双重否定”的规则,那么简单的单布尔值就可以了:

public static void Foo(bool useBaz)

public static void Foo(Ability useBaz)
然后
Foo(true)
,而
Foo(Ability.Enabled)
Foo(false)
,而
Foo(Ability.Disabled)
对大多数人来说都非常明显

但是,当您使用以下方法时:

public static void Foo(
    bool useBaz, 
    bool barIsHigh, 
    bool useFlibble, 
    bool ignoreCase)
那么,不管你是使用布尔还是通用枚举,它们最终在调用站点都是这样的:

Foo(false,true,false,false);
Foo(Ability.Enabled,Ability.Enabled,Ability.Disabled,Ability.Enabled);
两者都不漂亮

对手头的案例使用特定的枚举:

enum BarOption { Off, On }
enum BazConsidered { Low, High }
enum FlibbleOption { Off,  On  }
// for case sensitivity use System.StringComparison
然后你得到

Foo(Bar.On,
    BazConsidered.Low,
    FlibbleOption.On,
    StringComparison.IgnoreCase );
或者,如果所有状态都是简单的布尔状态,并且很可能保持这种状态,那么使用带标记的枚举更好

[Flags]
enum FooOptions
{
    None = 0,
    UseBaz = 1,
    BazConsideredHigh = 2,
    UseFlibble = 4,
}
那么你会:

Foo(FooOptions.UseBar | FooOptions.UseFlibble, StringComparison.IgnoreCase);

适当选择“活动”标志,以便仅指定不常见的内容,这将导致突出显示“不常见”用法。

使用带有有意义名称的
bool
参数有什么错

public void Foo(bool clickabilityEnabled, bool editabilityEnabled) { ... }
或者,更好的办法是少一点冗长:

public void Bar(bool isClickable, bool isEditable, bool isSerializable) { ... }

public void Baz(bool canClick, bool canEdit, bool canSerialize) { ... }

我会发现这比加载
enum
参数更具可读性。

是否有特别的原因让您不喜欢将true/false用于enabled/disabled?是的。特定的枚举,例如可点击性、可编辑性、可序列化性,提供了优异的可读性(如自文档)在调用站点,任何阅读代码的人都不需要跳转到方法定义来查看每个布尔值的作用或含义。在定义处编码的容易程度与在调用站点编码的容易程度之间取得平衡是一个有趣的问题。在大多数情况下,您应该优化调用站点的可读性/安全性/清晰性,因为您对方法的调用往往多于对方法的声明:)+1。特定的枚举还提供了一些类型安全性。您不会因为错过了正确的参数顺序而意外启用某些内容。谢谢。我想我会坚持使用我的特定枚举,例如,可点击性、可编辑性、可序列化性,因为它们在调用站点上提供了更高的可读性。方法定义可能是可读的,但调用看起来是什么样子?@AakashM:在我看来,调用站点的可读性也会比使用“泛型”更高类似OP请求的枚举:
Foo(true、false、true)
Foo(GenericEnum.Enabled,GenericEnum.Disabled,GenericEnum.Enabled)
@Luke(使用有意义的名称的bool参数有什么错?):嗯,特定的枚举,例如可点击性、可编辑性、可序列化性,提供了优异的可读性(如在自文档中)在调用站点,任何阅读代码的人都可以不必跳转到方法定义来查看每个布尔值的作用或含义。@Johann:我同意特定枚举可能会提供更好的可读性,但您的问题是如何用单个“通用”枚举替换这些特定枚举,这比使用命名良好的布尔参数可读性差。@Luke:你说得对。我的实际需求在一开始问了这个问题后就明确了。直到那时我才意识到我真的想要我一直在定义的特定枚举。