web-dev-qa-db-ja.com

C#intからenumへの変換

可能性のある複製:
C#で列挙するキャストint

次のコードがある場合:

enum foo : int
{
    option1 = 1,
    option2,
    ...
}

private foo convertIntToFoo(int value)
{
    // Convert int to respective Foo value or throw exception
}

変換コードはどのように見えますか?

53
TK.

IntをFooにキャストするだけで問題ありません:

int i = 1;
Foo f = (Foo)i;

定義されていない値をキャストしようとしても機能します。これから生じる唯一の害は、後で値を使用する方法にあります。

値が列挙型で定義されていることを確認したい場合は、Enum.IsDefinedを使用できます。

int i = 1;
if (Enum.IsDefined(typeof(Foo), i))
{
    Foo f = (Foo)i;
}
else
{
   // Throw exception, etc.
}

ただし、IsDefinedを使用すると、単にキャストするよりもコストがかかります。どちらを使用するかは、実装によって異なります。列挙型を使用する場合、ユーザー入力を制限するか、デフォルトのケースを処理することを検討してください。

また、enumがintを継承することを指定する必要がないことに注意してください。これがデフォルトの動作です。

115
Jon B

ここで明示的なキャストができると確信しています。

foo f = (foo)value;

Enumがintからinherits(?)を持っていると言う限り、これはあります。

enum foo : int

[〜#〜] edit [〜#〜]はい、デフォルトでは、列挙型の基になる型はintであることがわかります。ただし、char以外の任意の整数型を使用できます。

列挙型にない値からキャストして、無効な列挙型を生成することもできます。これは、実際にメモリ内の値を変更するのではなく、参照のタイプを変更するだけで機能すると思われます。

enum(C#リファレンス)
列挙型(C#プログラミングガイド)

16

キャストで十分です。 C#3.0を使用している場合は、列挙値を解析する便利な拡張メソッドを作成できます。

public static TEnum ToEnum<TInput, TEnum>(this TInput value)
{
    Type type = typeof(TEnum);

    if (value == default(TInput))
    {
        throw new ArgumentException("Value is null or empty.", "value");
    }

    if (!type.IsEnum)
    {
        throw new ArgumentException("Enum expected.", "TEnum");
    }

    return (TEnum)Enum.Parse(type, value.ToString(), true);
}
5
weiran
if (Enum.IsDefined(typeof(foo), value))
{
   return (Foo)Enum.Parse(typeof(foo), value);
}

お役に立てれば

編集この例の値は文字列であるため、質問がintを要求したため、この答えはダウン投票されました。私の謝辞;以下は少し明確になるはずです:-)

Type fooType = typeof(foo);

if (Enum.IsDefined(fooType , value.ToString()))
{
   return (Foo)Enum.Parse(fooType , value.ToString());
}
4
WestDiscGolf

継承は必要ありません。できるよ:

(Foo)1 

それが動作します ;)

2
Sergio