是否有任何理由在 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) 在我看来,使用位标志并不总是那么清楚你在做什么——你需要额外的知识元素。
例如,我有两种实现方式,一种带有位标志,另一种带有简单枚举:
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) 在我看来,使用位标志并不总是那么清楚你在做什么——你需要额外的知识元素。