29

この質問は、ジェネリックメソッド内での列挙型のキャストに関連しています

列挙型が与えられた

public enum Crustaceans
{
    Frog = 1,
    Toad = 4
}

列挙型のインスタンスを簡単に作成できます

short val = 4;
Crustaceans crusty = (Crustaceans) val;

ただし、

short val = 4;
object obj = (object) val;
Crustaceans crusty = (Crustaceans)obj;

無愛想な初期化を実行しようとすると、ランタイム例外がスローされます。

なぜこれが起こっているのか、そしてなぜそのようなことをすることが合法ではないのかを誰かが説明できますか?

私は本当にこれをやりたかったわけではありませんが、ジェネリックで同様のことが起こっていることを見つけようとすると、問題に遭遇します。事実上、それが隠れて起こっていることです。すなわち

public T dosomething<T>(short val) where T : new()
{
    T result = (T)(object) val;
    return result;
}

だから私がやろうとしているのは、例外をスローせずに短い値に設定して実際に正しい列挙値を初期化できる、列挙型と非列挙型(それほど重要ではありませんがいいでしょう)で動作するジェネリック関数を持っていることです。

4

6 に答える 6

53

このようなものがおそらくあなたを助けるでしょう:

public T dosomething<T>(object o)
{
   T enumVal= (T)Enum.Parse(typeof(T), o.ToString());
   return enumVal;
}

ただし、使用する明確な理由により、これは列挙型でのみ機能しますEnum.Parse(..)

たとえば、次のように使用します。

object o = 4;
dosomething<Crustaceans>(o);

Toadそれはあなたの場合に戻ります。

于 2012-08-16T08:05:33.463 に答える
5

Generics を使用できない場合があります (値を として取得する場合の WPF コンバーターのようにobject)。この場合int、列挙型が ではない可能性があるため、にキャストできませんint。これは、ジェネリックなしで行う一般的な方法です。例は WPF コンバーター内で提供されますが、内部のコードは一般的です。

using System;
using System.Windows;
using System.Windows.Data;

.
.
.

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    var enumType = value.GetType();
    var underlyingType = Enum.GetUnderlyingType(enumType);
    var numericValue = System.Convert.ChangeType(value, underlyingType);
    return numericValue;
}
于 2016-10-27T12:21:36.560 に答える