更新:2007 年 11 月
| TypeName | EnumsShouldHaveZeroValue | 
| CheckId | CA1008 | 
| 类别 | Microsoft.Design | 
| 是否重大更改 | 否 — 如果提示将 None 值添加到无标志枚举。是 — 如果提示重命名或移除任何枚举值。 | 
原因
未应用 System.FlagsAttribute 的枚举没有定义为零值的成员;或者应用了 FlagsAttribute 的枚举虽然定义了零值的成员,但其名称不是“None”,或者该枚举定义了多个为零值的成员。
规则说明
像其他值类型一样,未初始化枚举的默认值为零。无标志属性的枚举应定义零值的成员,这样默认值即为该枚举的有效值。如果合适,将该成员命名为“None”。否则,将零赋给最常用的成员。请注意,如果声明中未设置第一个枚举成员的值,则其默认值为零。
如果应用了 FlagsAttribute 的枚举定义零值成员,则其名称应为“None”,以指示枚举中尚未设置值。出于任何其他目的使用零值成员都与使用 FlagsAttribute 的目的相背,因为 AND 和 OR 按位运算符对该成员无用。这意味着,只能为一个成员赋值零。请注意,如果应用了标志属性的枚举中存在多个零值的成员,则 Enum.ToString() 会为非零成员返回不正确结果。
如何修复冲突
要为未应用标志属性的枚举修复与该规则的冲突,请定义一个零值的成员;这不属于重大更改。对于定义零值成员的无标志属性枚举,请将该成员命名为“None”,然后删除任何其他零值的成员;这属于重大更改。
何时禁止显示警告
除以前发布的带有标志属性的枚举外,请不要禁止显示与该规则有关的警告。
示例
下面的示例演示满足该规则的两个枚举和一个与该规则冲突的枚举 BadTraceOptions。
Imports System
Namespace DesignLibrary
   Public Enum TraceLevel
      Off     = 0
      AnError = 1
      Warning = 2
      Info    = 3
      Verbose = 4
   End Enum
   <Flags> _
   Public Enum TraceOptions
      None         =    0
      CallStack    = &H01
      LogicalStack = &H02
      DateTime     = &H04
      Timestamp    = &H08
   End Enum
   <Flags> _
   Public Enum BadTraceOptions
      CallStack    =    0
      LogicalStack = &H01
      DateTime     = &H02
      Timestamp    = &H04
   End Enum
   Class UseBadTraceOptions
      Shared Sub Main()
         ' Set the flags.
         Dim badOptions As BadTraceOptions = _
            BadTraceOptions.LogicalStack Or BadTraceOptions.Timestamp
         ' Check whether CallStack is set.
         If((badOptions And BadTraceOptions.CallStack) = _
             BadTraceOptions.CallStack)
            ' This 'If' statement is always true.
         End If
      End Sub
   End Class
End Namespace
using System;
namespace DesignLibrary
{
   public enum TraceLevel
   {
      Off     = 0,
      Error   = 1,
      Warning = 2,
      Info    = 3,
      Verbose = 4
   }
   [Flags]
   public enum TraceOptions
   {
      None         =    0,
      CallStack    = 0x01,
      LogicalStack = 0x02,
      DateTime     = 0x04,
      Timestamp    = 0x08,
   }
   [Flags]
   public enum BadTraceOptions
   {
      CallStack    =    0,
      LogicalStack = 0x01,
      DateTime     = 0x02,
      Timestamp    = 0x04,
   }
   class UseBadTraceOptions
   {
      static void Main()
      {
         // Set the flags.
         BadTraceOptions badOptions = 
            BadTraceOptions.LogicalStack | BadTraceOptions.Timestamp;
         // Check whether CallStack is set.
         if((badOptions & BadTraceOptions.CallStack) == 
             BadTraceOptions.CallStack)
         {
            // This 'if' statement is always true.
         }
      }
   }
}
using namespace System;
namespace DesignLibrary
{
   public enum class TraceLevel
   {
      Off     = 0,
      Error   = 1,
      Warning = 2,
      Info    = 3,
      Verbose = 4
   };
   [Flags]
   public enum class TraceOptions
   {
      None         =    0,
      CallStack    = 0x01,
      LogicalStack = 0x02,
      DateTime     = 0x04,
      Timestamp    = 0x08
   };
   [Flags]
   public enum class BadTraceOptions
   {
      CallStack    =    0,
      LogicalStack = 0x01,
      DateTime     = 0x02,
      Timestamp    = 0x04
   };
}
using namespace DesignLibrary;
void main()
{
   // Set the flags.
   BadTraceOptions badOptions = safe_cast<BadTraceOptions> 
      (BadTraceOptions::LogicalStack | BadTraceOptions::Timestamp);
   // Check whether CallStack is set.
   if((badOptions & BadTraceOptions::CallStack) == 
         BadTraceOptions::CallStack)
   {
      // This 'if' statement is always true.
   }
}