System.Enum派生型を対応する整数値に変換する汎用メソッドを作成します。キャストせずに、できれば文字列を解析せずに。
たとえば、私が欲しいのは次のようなものです:
// Trivial example, not actually what I'm doing.
class Converter
{
int ToInteger(System.Enum anEnum)
{
(int)anEnum;
}
}
しかし、これはうまくいかないようです。 Resharperは、「System.Enum」型の式を「int」型にキャストできないと報告しています。
今、私はこの解決策を思いつきましたが、私はむしろもっと効率的なものが欲しいです。
class Converter
{
int ToInteger(System.Enum anEnum)
{
return int.Parse(anEnum.ToString("d"));
}
}
助言がありますか?
キャストしたくない場合は、
Convert.ToInt32()
トリックを行うことができます。
直接キャスト((int)enumValue
経由)はできません。列挙型にはさまざまな基本型(int
、long
、byte
...)があるため、これも「危険」であることに注意してください。
より正式には:System.Enum
はInt32
と直接の継承関係を持たないため(両方ともValueType
sですが)、明示的なキャストは型システム内では正しくありません
オブジェクトにキャストしてからintにキャストすることで動作するようになりました:
public static class EnumExtensions
{
public static int ToInt(this Enum enumValue)
{
return (int)((object)enumValue);
}
}
これは見苦しく、おそらく最善の方法ではありません。私はそれをいじり続け、より良いものを思い付くことができるかどうかを確認します。
編集:Convert.ToInt32(enumValue)が同様に機能することを投稿しようとしており、MartinStettnerが私にそれを打ち負かしたことに気付きました。
public static class EnumExtensions
{
public static int ToInt(this Enum enumValue)
{
return Convert.ToInt32(enumValue);
}
}
テスト:
int x = DayOfWeek.Friday.ToInt();
Console.WriteLine(x); // results in 5 which is int value of Friday
編集2:コメントでは、誰かがこれはC#3.0でのみ機能すると言った。私はこれをVS2005でこのようにテストしましたが、うまくいきました:
public static class Helpers
{
public static int ToInt(Enum enumValue)
{
return Convert.ToInt32(enumValue);
}
}
static void Main(string[] args)
{
Console.WriteLine(Helpers.ToInt(DayOfWeek.Friday));
}
any enumをその基になる型に変換する必要がある場合(すべてのenumがint
によってサポートされているわけではありません)、次を使用できます。
return System.Convert.ChangeType(
enumValue,
Enum.GetUnderlyingType(enumValue.GetType()));
ヘルパーメソッドを使用して車輪を再発明する必要があるのはなぜですか? enum
値をその基になる型にキャストすることは完全に合法です。
タイピングが少なく、私の意見では読みやすいです...
int x = (int)DayOfWeek.Tuesday;
...のようなものではなく...
int y = Converter.ToInteger(DayOfWeek.Tuesday);
// or
int z = DayOfWeek.Tuesday.ToInteger();
私の答えから ここ :
次のようにe
を指定します。
Enum e = Question.Role;
その後、これらは動作します:
int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);
最後の2つは見苦しいです。最初のものはより読みやすいはずですが、2番目のものははるかに高速です。または、両方の世界で最高の拡張方法かもしれません。
public static int GetIntValue(this Enum e)
{
return e.GetValue<int>();
}
public static T GetValue<T>(this Enum e) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
return (T)(object)e;
}
今、あなたは呼び出すことができます:
e.GetValue<int>(); //or
e.GetIntValue();
System.Enum
からint
へは、私にとっては問題なく機能します( [〜#〜] msdn [〜#〜] にもあります)。おそらく、それはResharperのバグです。
Enumはbyte、sbyte、short、ushort、int、uint、long、ulongに制限されているため、いくつかの仮定を行うことができます。
利用可能な最大のコンテナを使用することにより、変換中の例外を回避できます。残念ながら、使用するコンテナは明確ではありません。なぜなら、ulongは負の数に対しては爆発し、longはlong.MaxValueとulong.MaxValueの間の数に対しては爆発するからです。基本となるタイプに基づいて、これらの選択肢を切り替える必要があります。
もちろん、結果がintに収まらない場合の対処方法を決定する必要があります。キャストは大丈夫だと思いますが、まだいくつかの落とし穴があります。
これが私の提案です。この関数を公開する場所を決めるのは読者に任せます。ヘルパーまたは拡張機能として。
public int ToInt(Enum e)
{
unchecked
{
if (e.GetTypeCode() == TypeCode.UInt64)
return (int)Convert.ToUInt64(e);
else
return (int)Convert.ToInt64(e);
}
}