列挙型は確かにコードを読みやすくします。注意すべきことがいくつかあります (少なくとも .net では)。
列挙型の基になるストレージは int であるため、デフォルト値は 0 になるため、0 が適切なデフォルトであることを確認する必要があります。(たとえば、構造体は作成時にすべてのフィールドがゼロに設定されているため、0 以外のデフォルトを指定する方法はありません。値が 0 でない場合は、int にキャストせずに列挙型をテストすることさえできません。スタイル悪い)
列挙型がコードに対して非公開である (公開されていない) 場合は、ここで読むのをやめることができます。
列挙型が何らかの方法で外部コードに公開されている場合、および/またはプログラムの外部に保存されている場合は、それらに明示的に番号を付けることを検討してください。コンパイラは自動的にそれらに 0 から番号を付けますが、値を指定せずに列挙型を再配置すると、欠陥が発生する可能性があります。
合法的に書ける
WriteMode illegalButWorks = (WriteMode)1000000;
file.Write( data, illegalButWorks );
これに対抗するには、特定できない列挙型 (パブリック API など) を使用するすべてのコードで、列挙型が有効かどうかを確認する必要があります。これは次の方法で行います
if (!Enum.IsDefined(typeof(WriteMode), userValue))
throw new ArgumentException("userValue");
の唯一の注意点Enum.IsDefined
は、リフレクションを使用しており、速度が遅いことです。また、バージョン管理の問題もあります。列挙値を頻繁に確認する必要がある場合は、次の方法を使用することをお勧めします。
public static bool CheckWriteModeEnumValue(WriteMode writeMode)
{
switch( writeMode )
{
case WriteMode.Append:
case WriteMode.OverWrite:
break;
default:
Debug.Assert(false, "The WriteMode '" + writeMode + "' is not valid.");
return false;
}
return true;
}
バージョン管理の問題は、古いコードが 2 つの列挙型を処理する方法しか知らない可能性があることです。3 番目の値を追加すると、Enum.IsDefined は true になりますが、古いコードでは必ずしもそれを処理できるとは限りません。おっと。
列挙型でできることはさらに多く[Flags]
、そのための検証コードは少し異なります。
ToString()
また、移植性のために、列挙型にcallを使用Enum.Parse()
し、それらを読み戻すときに使用する必要があることにも注意してください。両方ともToString()
列挙型Enum.Parse()
も処理できる[Flags]
ため、それらを使用しない理由はありません。コードを壊さずに列挙型の名前を変更することさえできないため、これはさらに別の落とし穴です。
ですから、自分自身に尋ねるとき、上記のすべてを比較検討する必要がある場合があります。