2017-11-29 9 views
0

コンパイル時に既知の型のforeachループでジェネリック関数を呼び出す方法はありますか?このコードはコンパイルされません。なぜなら、typeはDoSmthの有効なパラメータではありませんが、私は何をしたいのかを示しています。C#コンパイル時に知られているジェネリック型をループする

public class X { } 

    public class Y { } 

    public class Z { } 

    public class Example 
    { 
     public Example() 
     { 
      Types = new List<Type> 
      { 
       typeof(X), 
       typeof(Y), 
       typeof(Z) 
      }; 
     } 

     private List<Type> Types { get; } 

     public void DoAllTypes() 
     { 
      foreach (var type in Types) 
      { 
       DoSmth<type>(); 
      } 
     } 

     private void DoSmth<T>() 
     { 
      // ... do smth based on T 
     } 
    } 

編集:なぜ質問が重複していますか?私は特に「コンパイル時に知られている」と述べました。もう一方はReflectionsを使用して、コンパイル時に知られていない型を取得します。

+2

、あなたは何をするだけの型パラメータを受け入れる方法をしたい場合その型に基づいた何か、それを行う最も簡単な方法は 'DoSmth'のように' private void DoSmth(Type type) '... –

+0

と書かれています。実際に* 3つのメソッドが必要です。これらすべてのタイプは共通しているようには見えないので、共通の方法で行うことはあまりありません。 – HimBromBeere

答えて

3

あなたが保存することができ、デリゲート(Action):

public class Example 
{ 
    public Example() 
    { 
     Types = new List<Action> 
     { 
      DoSmth<X>, 
      DoSmth<Y>, 
      DoSmth<Z> 
     }; 
    } 

    private List<Action> Types { get; } 

    public void DoAllTypes() 
    { 
     foreach (var type in Types) 
     { 
      type(); 
     } 
    } 

    private void DoSmth<T>() 
    { 
     // ... do smth based on T 
    } 
} 

より良い方法 - 使用の継承:

public class A 
{ 
    public virtual void DoSmth() 
    { 
    } 
} 

public class X : A 
{ 
    public override void DoSmth() 
    { 

    } 
} 

public class Y : A 
{ 
    public override void DoSmth() 
    { 

    } 
} 

public class Z : A 
{ 
    public override void DoSmth() 
    { 

    } 
} 

public class Example 
{ 
    public Example() 
    { 
     Types = new List<A> 
     { 
      new X(), 
      new Y(), 
      new Z() 
     }; 
    } 

    private List<A> Types { get; } 

    public void DoAllTypes() 
    { 
     foreach (var type in Types) 
     { 
      type.DoSmth(); 
     } 
    } 
} 
+0

ありがとうと私は仕事をするためのアイデアをくれました。 –

+0

@WadimSmirnow galdが手伝ってください! – Backs

0

この場合、実際にgenericを使用していますか? switch statements with patternで解決する方法の例を次に示します。あなたの方法に

public void DoAllTypes() 
{ 
    foreach (var type in Types) 
    { 
     DoSmth(type); 
    } 
} 

private void DoSmth(Type t) 
{ 
    switch (this.value) { 
     case X xval: 
      //Handle type X 
      break; 
     case Y xval: 
      //Handle type Y 
      break; 
     //And so on... 
    } 
} 
関連する問題