2017-01-23 14 views
-2

のリストから私の問題は、このコードが含まれます。C#ジェネリックメソッドの戻り値の型タイプ

public static class MyStaticClass { 
    public class MyClass { 
     public List<object> MyObjects; 
     public List<Type> MyTypes; 

     public MyClass() { 
      MyObjects = new List<object>(){ 1, 0.5F }; 
      MyTypes = new List<Type>(){ typeof{int), typeof(float) } 
     } 

     public T GetObject<T>(int index) { 
      // Should return an instance of type MyTypes[index], and not object 
      return MyObjects[index] as MyTypes[index]; 
     } 
    } 

    public static void Main() { 
     MyClass myClass = new MyClass(); 
     int arg1 = myClass.GetObject(0); 
     float arg2 = myClass.GetObject(1); 
     MyMethod(arg1, arg2); 
    } 

    public static void MyMethod(int arg1, float arg2) { 
     // Does something 
    } 
} 

私はMyClassは、混合型の可変長のリストを保存します。私がこれを行うために知っている唯一の方法は、List<object>を保存することです。しかし、メソッド内でMyClass.MyObjectsの値を使用したいのですが、単に値をobjectとして取得すると、オブジェクトをint、floatなどに変換できないというエラーが送信されます。

問題は私はMyObjectsのオブジェクトの正確なサブタイプを知っていますが、TMyClass.GetObjectMyTypes[index]に設定する方法が見つかりません。私が見つけた唯一の解決策は、

int arg1 = myClass.MyObjects[0] as int; 
float arg2 = myClass.MyObjects[1] as float; 

を使用することですしかし、私はそれが私は一度だけ、オブジェクトの種類を設定してからちょうど自動的MyObjects内のオブジェクトをキャストするMyTypesを使用する必要があることになりたいです。

ありがとうございます。

+3

呼び出しメソッドは、各インデックスに格納されている型が分かっている必要があります。あなたはこのコードで何を達成しようとしていますか? –

+0

なぜ、単に 'T'にキャストしていないのですか? (そうです、それは合法です、実行時に変換が行われます) 'T 'と' MyTypes [index]'の不一致を検出する必要があると思いますか? –

+0

あなたのメソッド内でキャストできたとしても、呼び出し側のコードでは、ジェネリックパラメータとして渡す型を知る必要があります。しかし、あなたの呼び出しコードが実際の型を知っていれば、返されたオブジェクトをその特定の型にキャストする際に問題を見ることができません。 – HimBromBeere

答えて

0

私は間違いがどこにあるか知っていると思います。たとえば、署名が必要なメソッドがあるとします。 intの場合、オブジェクトがintにキャストされているかどうかは、Typeintを指しているにもかかわらず、あるオブジェクトをTypeにキャストしたかどうかをコンパイラは知ることができません。私のために働いたのは、objectsにしかならないMyMethodのコピーを作成した後、そのメソッドでサブタイプにキャストし、サブタイプの署名でMyMethodを実行することでした。

0

各オブジェクトはすでにオブジェクト内に型情報を格納しているため、格納型は冗長です。

あなたが結果をキャストまたは明示的に型を定​​義することができ、ここでは後者です:

public static class MyStaticClass { 
    public class MyClass { 
     public List<object> MyObjects; 

     public MyClass() { 
      MyObjects = new List<object>(){ 1, 0.5F }; 
     } 

     public T GetObject<T>(int index) { 
      var item = MyObjects[index]; 
      if(typeof(T) != item.GetType()) 
       throw new InvalidCastException(); 

      return (T) item; 
     } 
    } 

    public static void Main() { 
     MyClass myClass = new MyClass(); 
     int arg1 = myClass.GetObject<int>(0); 
     float arg2 = myClass.GetObject<float>(1); 
     MyMethod(arg1, arg2); 
    } 

    public static void MyMethod(int arg1, float arg2) { 
     // Does something 
    } 
} 

あなたが任意のオブジェクトにはgettype()を使用することができますので、あなたは、未知のオブジェクトのコレクションを持っている場合、あなただけ把握することができそれらの型は実行時に型付けされ、それに応じて動作します。