Sunday, November 2, 2008

Enum Usage Guidelines

The following rules outline the usage guidelines for enumerations:
1. Use an enum to strongly type parameters, properties, and return types. Always define enumerated values using an enum if they are used in a parameter or property. This allows development tools to know the possible values for a property or parameter. The following example shows how to define an enum type.
Visual Basic
Public Enum FileMode
Append
Create
CreateNew
Open
OpenOrCreate
Truncate
End Enum
C#
public enum FileMode
{
Append,
Create,
CreateNew,
Open,
OpenOrCreate,
Truncate
}

The following example shows the constructor for a FileStream object that uses the FileMode enum.
Visual Basic
Public Sub New(ByVal path As String, _
ByVal mode As FileMode)
C#
public FileStream(string path, FileMode mode);
2. Use the System.FlagsAttribute class to create custom attribute for an enum if a bitwise OR operation is to be performed on the numeric values. This attribute is applied in the following code example.
Visual Basic
_
Public Enum Bindings
IgnoreCase = &H1
NonPublic = &H2
Static = &H4
InvokeMethod = &H100
CreateInstance = &H200
GetField = &H400
SetField = &H800
GetProperty = &H1000
SetProperty = &H2000
DefaultBinding = &H10000
DefaultChangeType = &H20000
[Default] = DefaultBinding Or DefaultChangeType
ExactBinding = &H40000
ExactChangeType = &H80000
BinderBinding = &H100000
BinderChangeType = &H200000
End Enum
C#
[Flags]
public enum Bindings
{
IgnoreCase = 0x01,
NonPublic = 0x02,
Static = 0x04,
InvokeMethod = 0x0100,
CreateInstance = 0x0200,
GetField = 0x0400,
SetField = 0x0800,
GetProperty = 0x1000,
SetProperty = 0x2000,
DefaultBinding = 0x010000,
DefaultChangeType = 0x020000,
Default = DefaultBinding | DefaultChangeType,
ExactBinding = 0x040000,
ExactChangeType = 0x080000,
BinderBinding = 0x100000,
BinderChangeType = 0x200000
}

Note An exception to this rule is when encapsulating a Win32 API. It is common to have internal definitions that come from a Win32 header. You can leave these with the Win32 casing, which is usually all capital letters.
3. Use an enum with the flags attribute only if the value can be completely expressed as a set of bit flags. Do not use an enum for open sets (such as the operating system version).
4. Do not assume that enum arguments will be in the defined range. Perform argument validation as illustrated in the following code example.
Visual Basic
Public Sub SetColor(newColor As Color)
If Not [Enum].IsDefined(GetType(Color), newColor) Then
Throw New ArgumentOutOfRangeException()
End If
End Sub
C#
public void SetColor (Color color)
{
if (!Enum.IsDefined (typeof(Color), color)
throw new ArgumentOutOfRangeException();
}
5. Use an enum instead of static final constants.
6. Use type Int32 as the underlying type of an enum unless either of the following is true:
• The enum represents flags and there are currently more than 32 flags, or the enum might grow to many flags in the future.
• The type needs to be different from int for backward compatibility.
7. Do not use a non-integral enum type. Use only Byte, Int16, Int32, or Int64.
8. Do not use an Enum suffix on enum types.

No comments: