CA1008: Enumerationen müssen einen Wert von 0 (null) aufweisen
TypeName |
EnumsShouldHaveZeroValue |
CheckId |
CA1008 |
Kategorie (Category) |
Microsoft.Design |
Unterbrechende Änderung |
Nicht unterbrechend – Wenn Sie aufgefordert werden, einer Enumeration ohne Flag-Attribut einen None-Wert hinzuzufügen. Unterbrechend – Wenn Sie aufgefordert werden, einen Enumerationswert umzubenennen oder zu entfernen. |
Ursache
Eine Enumeration, auf die FlagsAttribute nicht angewendet wird, definiert keinen Member mit einem Wert von 0 (null), bzw. eine Enumeration, auf die FlagsAttribute angewendet wird, definiert einen Member mit einem Wert von 0 (null), ihr Name lautet jedoch nicht "None", oder die Enumeration definiert mehrere Member mit dem Wert 0 (null).
Regelbeschreibung
Der Standardwert einer nicht initialisierten Enumeration ist ebenso wie der anderer Werttypen 0 (null).Eine Enumeration ohne das Flags-Attribut sollte einen Member mit dem Wert 0 (null) definieren, damit der Standardwert ein gültiger Wert der Enumeration ist.Geben Sie dem Member gegebenenfalls den Namen "None".Weisen Sie andernfalls dem am häufigsten verwendeten Member den Wert 0 (null) zu.Wenn der Wert des ersten Enumerationsmembers in der Deklaration nicht festgelegt wird, ist 0 (null) der Standardwert.
Wenn eine Enumeration, auf die FlagsAttribute angewendet wird, einen Member mit dem Wert 0 (null) definiert, sollte dieser den Namen "None" haben, um anzugeben, dass in der Enumeration keine Werte festgelegt wurden.Die Verwendung eines Members mit dem Wert 0 (null) für andere Zwecke widerspricht der Verwendung von FlagsAttribute dahingehend, dass die bitweisen Operatoren AND und OR für den Member nutzlos sind.Dies impliziert, dass nur einem Member der Wert 0 (null) zugewiesen werden sollte.Wenn eine Enumeration mit dem Flags-Attribut mehrere Member mit dem Wert 0 (null) enthält, gibt Enum.ToString() für die Member, die nicht den Wert 0 (null) aufweisen, falsche Ergebnisse zurück.
Behandeln von Verstößen
Um einen Verstoß gegen diese Regel zu beheben, definieren Sie bei Enumerationen ohne Flags-Attribut einen Member mit dem Wert 0 (null). Dies ist eine nicht unterbrechende Änderung.Geben Sie bei Enumerationen, die einen Member mit dem Wert 0 (null) definieren, diesem Member den Namen "None", und löschen Sie alle übrigen Member, die einen Wert von 0 (null) aufweisen. Dies ist eine unterbrechende Änderung.
Wann sollten Warnungen unterdrückt werden?
Unterdrücken Sie eine Warnung dieser Regel nur bei Enumerationen mit dem Flags-Attribut, die zuvor versendet wurden.
Beispiel
Das folgende Beispiel zeigt zwei Enumerationen, die der Regel entsprechen, und eine Enumeration, BadTraceOptions, die gegen die Regel verstößt.
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.
}
}
Verwandte Regeln
CA2217: Enumerationen nicht mit FlagsAttribute markieren
CA1700: Enumerationswerte nicht mit "Reserviert" benennen
CA1712: Keine Typnamen als Präfixe für Enumerationswerte verwenden
CA1028: Der Enumerationsspeicher sollte Int32 sein.
CA1027: Enumerationen mit FlagsAttribute markieren