System.Reflection.TypeAttributes 是带有 FlagsAttribute 的病态枚举类型吗?
Is System.Reflection.TypeAttributes a sick enum type with the FlagsAttribute?
枚举类型 System.Reflection.TypeAttributes
显得相当病态。它带有[Flags]
属性,并且有不少于四个常量零的同义词。来自 Visual-Studio 生成的 "metadata":
#region Assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\mscorlib.dll
#endregion
using System.Runtime.InteropServices;
namespace System.Reflection
{
//
// Summary:
// Specifies type attributes.
[ComVisible(true)]
[Flags]
public enum TypeAttributes
{
//
// Summary:
// Specifies that the class is not public.
NotPublic = 0,
//
// Summary:
// Specifies that class fields are automatically laid out by the common language
// runtime.
AutoLayout = 0,
//
// Summary:
// Specifies that the type is a class.
Class = 0,
//
// Summary:
// LPTSTR is interpreted as ANSI.
AnsiClass = 0,
// (followed by non-zero members...)
为什么有人会在带有 FlagsAttribute
的枚举类型中使用四个名称来表示零?看起来真的很疯狂。
看看后果:
var x = default(System.Reflection.TypeAttributes); // 0
var sx = x.ToString(); // "NotPublic"
var y = (System.Reflection.TypeAttributes)(1 << 20); // 1048576
var sy = y.ToString(); // "AutoLayout, AnsiClass, Class, BeforeFieldInit"
此处 x
的字符串表示形式,类型的零值,变为 "NotPublic"
。而非零的字符串表示 y
变为 "AutoLayout, AnsiClass, Class, BeforeFieldInit"
。关于 y
,请注意它只设置了一个位 (1<<20
),名称 BeforeFieldInit
本身就准确地说明了该位。所有其他三个名称 AutoLayout, AnsiClass, Class,
对值的贡献为零。
这是怎么回事?
为什么要这样设计?
ToString()
表示在很大程度上是无关紧要的
当某些选项是非二进制时,这种模式很常见;例如,有 3 个可能的选项。在那种情况下,您可以指定 2 位来携带这 3 个选项(留下 4 个未使用),并且 "default" 选项(逻辑上)将是 00
。这意味着是的,0
.
会有多个同义词
注意:这可能 也 发生在纯二元期权中,如果枚举作者想让它更明确——因为调用者不需要知道哪些是 "on" 和 "off".
基本上不用担心ToString()
枚举类型 System.Reflection.TypeAttributes
显得相当病态。它带有[Flags]
属性,并且有不少于四个常量零的同义词。来自 Visual-Studio 生成的 "metadata":
#region Assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\mscorlib.dll
#endregion
using System.Runtime.InteropServices;
namespace System.Reflection
{
//
// Summary:
// Specifies type attributes.
[ComVisible(true)]
[Flags]
public enum TypeAttributes
{
//
// Summary:
// Specifies that the class is not public.
NotPublic = 0,
//
// Summary:
// Specifies that class fields are automatically laid out by the common language
// runtime.
AutoLayout = 0,
//
// Summary:
// Specifies that the type is a class.
Class = 0,
//
// Summary:
// LPTSTR is interpreted as ANSI.
AnsiClass = 0,
// (followed by non-zero members...)
为什么有人会在带有 FlagsAttribute
的枚举类型中使用四个名称来表示零?看起来真的很疯狂。
看看后果:
var x = default(System.Reflection.TypeAttributes); // 0
var sx = x.ToString(); // "NotPublic"
var y = (System.Reflection.TypeAttributes)(1 << 20); // 1048576
var sy = y.ToString(); // "AutoLayout, AnsiClass, Class, BeforeFieldInit"
此处 x
的字符串表示形式,类型的零值,变为 "NotPublic"
。而非零的字符串表示 y
变为 "AutoLayout, AnsiClass, Class, BeforeFieldInit"
。关于 y
,请注意它只设置了一个位 (1<<20
),名称 BeforeFieldInit
本身就准确地说明了该位。所有其他三个名称 AutoLayout, AnsiClass, Class,
对值的贡献为零。
这是怎么回事?
为什么要这样设计?
ToString()
表示在很大程度上是无关紧要的
当某些选项是非二进制时,这种模式很常见;例如,有 3 个可能的选项。在那种情况下,您可以指定 2 位来携带这 3 个选项(留下 4 个未使用),并且 "default" 选项(逻辑上)将是 00
。这意味着是的,0
.
注意:这可能 也 发生在纯二元期权中,如果枚举作者想让它更明确——因为调用者不需要知道哪些是 "on" 和 "off".
基本上不用担心ToString()