是否有任何理由在 C# 中使用枚举参数而不是位标志?

Is there any reason to use enum params over bit flags in c#?

例如,我有两种实现方式,一种带有位标志,另一种带有简单枚举:

1) 位标志

[Flags]
public enum LettersBitFlags
{
    A = 1,
    B = 2,
    C = 4,
    D = 8
}
public static bool IsLetterBBitFlags(LettersBitFlags letters)
{
    return (letters & LettersBitFlags.B) != 0;
}

2) 简单枚举

public enum Letters
{
    A,
    B,
    C,
    D
}
public static bool IsLetterBParams(params Letters[] letters)
{
    return letters.Any(x => x == Letters.B);
}

它们显然可以这样使用:

Console.WriteLine(IsLetterBBitFlags(LettersBitFlags.A | LettersBitFlags.D)); //false
Console.WriteLine(IsLetterBBitFlags(LettersBitFlags.B | LettersBitFlags.C)); //true

Console.WriteLine(IsLetterBParams(Letters.A, Letters.D)); //false
Console.WriteLine(IsLetterBParams(Letters.B, Letters.C)); //true

选择一个而不是另一个有什么实际原因吗?如我所见,它们给出了相同的结果,但也许某些性能或其他任何东西应该让我使用一个而不使用另一个?

当您以某些字节/整数位表示数据时,第一个选项很好,并且数据可能包含 1 个或多个枚举值,然后您可以检查数据是否有标志。

它们有不同的含义。标志的特点是将它们放在一起是有意义的;枚举只是离散的数据块,它们在幕后是数字的事实只不过是一个实现细节。

如果您在 没有 意义的地方使用标志或将它们中的两个放在一起,您将严重误导任何前来使用您的数据类型的人。相反,如果你在表示标志的地方使用枚举,那么你将不得不手动捕获和命名许多枚举案例。

位标志的优点:

1) flags 属性为您提供比枚举数组更好的 ToString() 行为。

2) 您可以在一个变量中存储多个值(因此不需要数组)。这在内存限制操作中可能很重要。

3) 方法 Enum.HasFlag 存在,因此您实际上不必实现静态 class.

缺点:

1) 您不能在标志中存储相同值的多个实例 - on/off。您的数组可以有多个相同值的实例。

2) 如果需要,任何 = 0 值都必须单独检查。

3) 在我看来,使用位标志并不总是那么清楚你在做什么——你需要额外的知识元素。