任意のタイプの文字列のみを表示していることに注意してください。いずれの場合も、可能であればより多くの値に拡張する方法について説明します。
列挙型をキーとして使用する
列挙型を辞書のキーとして使用できます (一意にしたいので、一部のヘルパー クラスで静的にして読み取り専用にします)。
private static readonly Dictionary<MyEnum, string> _dict =
{
//Using dictionary initialization
{MyEnum.MyValue, "The text for MyValue"},
{MyEnum.MyOtherValue, "Some other text"},
{MyEnum.YetAnotherValue, "Something else"}
}
public static readonly Dictionary<MyEnum, string> Dict
{
get
{
return _dict;
}
}
関連付けられた値にアクセスします。
string text = Dict[MyEnumEmu.MyValue];
または:
string text;
if (Dict.TryGetValue(MyEnumEmu.MyValue, out text))
{
//It has the value
}
else
{
//It doesn't have the value
}
このようにして、列挙値に関連付けられた文字列にアクセスできます。次に、辞書を公開して、対応する値を読み取ることができます。
複数の値を格納するには、複合型が必要になります。文字列ではなく、カスタムタイプを使用してください。または、利用可能な場合は使用できますTuples
。
へのアクセスはDictionary
余計な煩わしさを意味するかもしれませんが、うまくいけば、スレッド化の問題も意味しません。
Enum.GetName
Enum.GetNameを使用して、列挙型の値の名前を読み取ることができます。
string text = Enum.GetName(MyEnum.MyValue);
//text will have the text "MyValue"
//or
var some = MyEnum.MyValue;
string text = Enum.GetName(some);
注:ToString()
あまりにも動作するはずです。
残念ながら、これは文字列以外では機能しません。
また、テキストをそこに置くことができないという欠点もあります (有効な識別子である必要があります)。
カスタム属性
属性タイプを宣言する必要があります。
[AttributeUsage(AttributeTargets.Field)]
public class EnumValueAttribute : System.Attribute
{
public readonly string _value;
public string Value
{
get
{
return _value;
}
}
public HelpAttribute(string value) // value is a positional parameter
{
//beware: value can be null...
// ...but we don't want to throw exceptions here
_value = value;
}
}
次に、列挙型に属性を適用します。
public enum MyEnum
{
[EnumValue("The text for MyValue")]
MyValue = 1,
[EnumValue("Some other text")]
MyOtherValue = 2,
[EnumValue("Something else")]
YetAnotherValue = 3
}
最後に、属性を読み戻す必要があります。
public static string GetValue(MyEnumenumValue)
{
FieldInfo fiendInfo = typeof(MyEnum).GetField(enumValue.ToString());
if (!ReferenceEquals(fiendInfo, null))
{
object[] attributes = fieldInfo.GetCustomAttributes(typeof(EnumValueAttribute), true);
if (!ReferenceEquals(attributes, null) && attributes.Length > 0)
{
return ((EnumValueAttribute)attributes[0]).Value;
}
}
//Not valid value or it didn't have the attribute
return null;
}
これで、次のように呼び出すことができます。
string text = GetValue(MyEnum.MyValue);
//text will have the text "MyValue"
//or
var some = MyEnum.MyValue;
string text = GetValue(some);
属性クラスにさらにフィールドを追加し、それらを使用して必要な他の値を渡すことができます。
ただし、これにはリフレクションが必要であり、サンドボックスで実行している場合は利用できない場合があります。また、毎回属性を取得し、プロセス内で存続期間の短いオブジェクトをいくつか作成します。
列挙型をエミュレート
public コンストラクターを持たず、それ自体の静的な読み取り専用インスタンスを公開する、封印されたクラスで列挙型をエミュレートできます。
public sealed class MyEnumEmu
{
private static readonly string myValue = new MyEnumEmu("The text for MyValue");
private static readonly string myOtherValue = new MyEnumEmu("Some other text");
private static readonly string yetAnotherValue = new MyEnumEmu("Something else");
public static MyEnumEmu MyValue
{
get
{
return myValue;
}
}
public static MyEnumEmu MyOtherValue
{
get
{
return myOtherValue;
}
}
public static MyEnumEmu YetAnotherValue
{
get
{
return yetAnotherValue;
}
}
private string _value;
private MyEnumEmu(string value)
{
//Really, we are in control of the callers of this constructor...
//... but, just for good measure:
if (value == null)
{
throw new ArgumentNullException("value");
}
else
{
_value = value;
}
}
public string Value
{
get
{
return _value;
}
}
}
いつものように使用してください:
var some = MyEnumEmu.MyValue;
関連付けられた値にアクセスします。
string text = MyEnumEmu.MyValue.Value;
//text will have the text "MyValue"
//or
string text = some.Value;
これはより柔軟で、文字列の代わりに複合型を使用するか、複数の値を渡すためにフィールドを追加することができます。
しかし...それは実際には列挙型ではありません。