System.Reflection.TypeAttributes是一个带有FlagsAttribute的病态枚举类型吗?

时间:2016-10-07 14:41:21

标签: c# .net enums base-class-library enum-flags

枚举类型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,对值的贡献为零。

发生了什么事?

为什么要这样设计?

1 个答案:

答案 0 :(得分:3)

ToString()表示在很大程度上无关紧要

当某些选项是非二进制时,这种模式很常见;例如,有3种可能的选择。在这种情况下,您可以指定2位来承载这3个选项(剩下4个未使用),“默认”选项将是(逻辑上)00。这意味着是的,0会有多个同义词。

注意:这可能在纯二进制选项中发生,如果枚举作者想要使其更明确 - 因为调用者不需要知道哪些是“on”,哪些是“关”。

基本上,不要担心ToString()

相关问题