【发布时间】:2017-02-16 14:43:03
【问题描述】:
枚举类型System.Reflection.TypeAttributes 显得相当病态。它带有[Flags] 属性,并且对于常数零有不少于四个 的同义词。来自 Visual-Studio 生成的“元数据”:
#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, 对值的贡献为零。
发生了什么事?
为什么要这样设计?
【问题讨论】:
-
@ChrisBint 我不确定你的意思?
-
这些名称来自 CLI 规范,Ecma 335。它们使枚举定义尽可能接近规范,这并没有什么不好的。程序集元数据首先过于紧凑,在一个字段中尽可能多地打包选项。现在有点不定型也很重要,他们从来没有试图让它变得友好。它只对非常低级的程序集转储代码很重要,而不是盲目依赖 ToString() 的那种代码。
标签: c# .net enums base-class-library enum-flags