关于Enum Flag的最大大小



我有一个问题。

我目前正在学习枚举函数中的Flag。然后我在想,我能指定的枚举标志的最大尺寸是多少?

我现在标记的标志如下。

A = 1 << 0,
B = 1 << 1,
C = 1 << 2,
ZZZ = 1 << MaxSize(?)

我对Max size的值很好奇。

谢谢你的阅读,可能有语法错误,因为它是翻译的。: -)

以下是我的随机想法,不分先后:

  • 必读:
    • https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/enum
    • https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/enum

  • 在。net中,enum类型本质上是枚举底层类型的一组命名常量。
    • 虽然c#编译器不允许在枚举值与其底层类型之间进行隐式转换(0除外)。
  • 这被记录在。net公共语言基础结构规范:ECMA-335,第5版(2010),第34页。
  • 在c#中,enum可以使用任何。net的内置整数类型作为底层类型(截至2021年的。net 5,我们仍然限于与2001年相同的8个整数字节,但我们可能最终得到一个真正的Int128,但那还需要几年的时间):
    • ByteSByte(1 octet: 8 bits,分别为0-255-128~127)。
    • UInt16Int16(2字节即2字节组:16位,分别为0-65535-3276832767)。
    • UInt32Int32(4字节,32位等)。
    • UInt64Int64(8字节,64位等)。
    • (我相信。net规范在技术上允许Boolean/bool被用作enum底层类型,但c#不允许)。

很明显,Int64UInt64(对shift键过敏的人又称longulong)都提供了最宽的"空格";对于位值:毕竟有64位可以使用,而其他底层类型只能给你32位、16位或可怜的8位。


enum中没有成员数量的限制,但是很明显,具有较小基础类型的枚举将比较大的类型更快地耗尽它们的可能值集,并且最终会重复它们自己。

enum类型可以有多个具有不同名称的成员共享相同的整数值,但是在CLR内部无法区分一个成员和另一个成员。


我可以指定为枚举标志的最大大小是多少?

如果你指的是底层类型,那么直接的答案是Int64(long)或UInt64(ulong)。

如果你问的是枚举成员可以拥有的最大,那么它将是YourUnderlyingType.MaxValue,例如:

enum IntSizedEnum : Int32
{
LargestValue = Int32.MaxValue
}
enum BiggerEnum : UInt64
{
EvenLargerLargestValue = UInt64.MaxValue
}

如果你问的是设置的位数,那么如果你使用Int64UInt64,你可以得到64位,或单独的标志-甚至用位字面量逐位定义它们,例如:

enum BiggerEnum : UInt64
{
All64Bits = 0b_11111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111
}

对于标志,你可以做一些疯狂的事情:

[Flags]
enum BiggerEnum : UInt64
{
FlagsCombination = Bit_32 | Bit_33 | Bit_34,
Bit_0  = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001,
Bit_1  = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000010,
Bit_2  = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000100,
Bit_3  = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00001000,
Bit_4  = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00010000,
Bit_5  = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00100000,
Bit_6  = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_01000000,
Bit_7  = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_10000000,
Bit_8  = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000001_00000000,
Bit_9  = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000010_00000000,
Bit_10 = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000100_00000000,
Bit_11 = 0b00000000_00000000_00000000_00000000_00000000_00000000_00001000_00000000,
Bit_12 = 0b00000000_00000000_00000000_00000000_00000000_00000000_00010000_00000000,
Bit_13 = 0b00000000_00000000_00000000_00000000_00000000_00000000_00100000_00000000,
Bit_14 = 0b00000000_00000000_00000000_00000000_00000000_00000000_01000000_00000000,
Bit_15 = 0b00000000_00000000_00000000_00000000_00000000_00000000_10000000_00000000,
Bit_16 = 0b00000000_00000000_00000000_00000000_00000000_00000001_00000000_00000000,
Bit_17 = 0b00000000_00000000_00000000_00000000_00000000_00000010_00000000_00000000,
Bit_18 = 0b00000000_00000000_00000000_00000000_00000000_00000100_00000000_00000000,
Bit_19 = 0b00000000_00000000_00000000_00000000_00000000_00001000_00000000_00000000,
Bit_20 = 0b00000000_00000000_00000000_00000000_00000000_00010000_00000000_00000000,
Bit_21 = 0b00000000_00000000_00000000_00000000_00000000_00100000_00000000_00000000,
Bit_22 = 0b00000000_00000000_00000000_00000000_00000000_01000000_00000000_00000000,
Bit_23 = 0b00000000_00000000_00000000_00000000_00000000_10000000_00000000_00000000,
Bit_24 = 0b00000000_00000000_00000000_00000000_00000001_00000000_00000000_00000000,
Bit_25 = 0b00000000_00000000_00000000_00000000_00000010_00000000_00000000_00000000,
Bit_26 = 0b00000000_00000000_00000000_00000000_00000100_00000000_00000000_00000000,
Bit_27 = 0b00000000_00000000_00000000_00000000_00001000_00000000_00000000_00000000,
Bit_28 = 0b00000000_00000000_00000000_00000000_00010000_00000000_00000000_00000000,
Bit_29 = 0b00000000_00000000_00000000_00000000_00100000_00000000_00000000_00000000,
Bit_30 = 0b00000000_00000000_00000000_00000000_01000000_00000000_00000000_00000000,
Bit_31 = 0b00000000_00000000_00000000_00000000_10000000_00000000_00000000_00000000,
Bit_32 = 0b00000000_00000000_00000000_00000001_00000000_00000000_00000000_00000000,
Bit_33 = 0b00000000_00000000_00000000_00000010_00000000_00000000_00000000_00000000,
Bit_34 = 0b00000000_00000000_00000000_00000100_00000000_00000000_00000000_00000000,
Bit_35 = 0b00000000_00000000_00000000_00001000_00000000_00000000_00000000_00000000,
Bit_36 = 0b00000000_00000000_00000000_00010000_00000000_00000000_00000000_00000000,
Bit_37 = 0b00000000_00000000_00000000_00100000_00000000_00000000_00000000_00000000,
Bit_38 = 0b00000000_00000000_00000000_01000000_00000000_00000000_00000000_00000000,
Bit_39 = 0b00000000_00000000_00000000_10000000_00000000_00000000_00000000_00000000,
Bit_40 = 0b00000000_00000000_00000001_00000000_00000000_00000000_00000000_00000000,
Bit_41 = 0b00000000_00000000_00000010_00000000_00000000_00000000_00000000_00000000,
Bit_42 = 0b00000000_00000000_00000100_00000000_00000000_00000000_00000000_00000000,
Bit_43 = 0b00000000_00000000_00001000_00000000_00000000_00000000_00000000_00000000,
Bit_44 = 0b00000000_00000000_00010000_00000000_00000000_00000000_00000000_00000000,
Bit_45 = 0b00000000_00000000_00100000_00000000_00000000_00000000_00000000_00000000,
Bit_46 = 0b00000000_00000000_01000000_00000000_00000000_00000000_00000000_00000000,
Bit_47 = 0b00000000_00000000_10000000_00000000_00000000_00000000_00000000_00000000,
Bit_48 = 0b00000000_00000001_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_49 = 0b00000000_00000010_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_50 = 0b00000000_00000100_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_51 = 0b00000000_00001000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_52 = 0b00000000_00010000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_53 = 0b00000000_00100000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_54 = 0b00000000_01000000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_55 = 0b00000000_10000000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_56 = 0b00000001_00000000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_57 = 0b00000010_00000000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_58 = 0b00000100_00000000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_59 = 0b00001000_00000000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_60 = 0b00010000_00000000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_61 = 0b00100000_00000000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_62 = 0b01000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000,
Bit_63 = 0b10000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000
}
// Usage:
BiggerEnum value = default;
value |= BiggerEnum.Bit_32 | BiggerEnum.Bit_33 | BiggerEnum.Bit_34;
Console.WriteLine( value == BiggerEnum.FlagsCombination ); // true
Console.WriteLine( value ); // 30064771072

…但是你真的不应该那样做。

如果你想在位移中使用它,它将是

1 << 31

-2147483648

int恰好有32位所以如果你输入

1 << 32

意味着取值1

00000000 00000000 00000000 00000001

然后把所有的位都向左移动32次结果仍然是1或者

1 << 0

将底层枚举类型更改为ulong是没有用的。至少不使用位移运算符,因为位移运算符总是只能对int进行位移。值(参见此处的示例)。


如果你真的想疯,看看戴的回答!手动实际上,您可以将标志扩展为使用底层类型ulong,并拥有最多64的值。

最新更新