1

リフレクションを使用して、「MyTypes」の各リストを T:MyDataObject の制約を持つジェネリック メソッドに渡すにはどうすればよいですか?

public interface IAllMyTypes
{
    List<FirstType> MyType1 { get; set; }
    List<SecondType> MyType2 { get; set; }
    List<ThirdType> MyType3 { get; set; }
}

FirstType、SecondType、および ThirdType は MyDataObject から継承しますが (以下に示すように)、異なるプロパティを持ちます。

public class FirstType : MyDataObject
{
  //various properties
}   

このシグネチャを使用してデータをメソッドに渡すことができませんでした:

void DoSomething<T>(IEnumerable<T> enumerable) where T : MyDataObject;

エラーは、「型引数を推論できません」というものです。

これが私の失敗した試みです:

public void DoSomethingWithAllMyTypes(IAllMyTypes allMyTypes)
{
    foreach (PropertyInfo propertyInfo in allMyTypes.GetType().GetProperties())
    {
        var x = propertyInfo.GetValue(allMyTypes) as IList;//im not sure what to do here
        if(x==null) throw new Exception("still wrong");

        DoSomething(x);
    }
}   

次のようなプロパティを直接指定すると、DoSomething(..) のすべてのコードが正しく機能します。

public void DoSomethingWithAllMyTypes(IAllMyTypes allMyTypes)
{
    DoSomething(allMyTypes.MyType1);
    DoSomething(allMyTypes.MyType2);
    DoSomething(allMyTypes.MyType3);
}
4

3 に答える 3

2

リフレクションを使用する場合は、リフレクションを使用してヘルパー メソッドを呼び出すこともできます。

ジェネリックMethodInfoメソッドへのを取得し、実際のメソッドへのジェネリック メソッド リフレクション ハンドルを作成する必要があります。その場合、ジェネリック メソッドの型は実行時に取得する必要があります。InvokeT

public void DoSomethingWithAllMyTypes(IAllMyTypes allMyTypes)
{
    var method = this.GetType().GetMethod("DoSomething", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
    foreach (PropertyInfo propertyInfo in allMyTypes.GetType().GetProperties())
    {
        var x = propertyInfo.GetValue(allMyTypes, null);
        if(x==null) throw new Exception("still wrong");

        // obtain the type from the property - other techniques can be used here.
        var genericMethod = method.MakeGenericMethod(new[] {propertyInfo.PropertyType.GetGenericArguments()[0]})
        //execute the generic helper
        genericMethod.Invoke(this, new[]{x});
    }
} 

public void DoSomething<T>(IList<T> list) where T : MyDataObject {

}
于 2013-11-11T17:10:48.900 に答える
0

物事を過度に複雑にすることなく、自分が行った方法でデータを構造化する必要があるケースを見つけるのに苦労しています。正当なケースを見つけた場合は、コメントしてください。お客様のニーズを反映するように回答を更新します。

基本クラスから始めて、抽象化し、抽象メソッドを入れることができますDoSomething

public abstract class MyDataObject{
  public string SomeSharedProperty{get;set;}
  protected abstract DoSomething(); 
}

public class FirstType: MyDataObject{ 
  protected override DoSomething(){
    Console.WriteLine(SomeSharedProperty);
  }
}


public class Consumer{
  public void DoSomethingWithAllMyTypes(List<MyDataObject> source)
  {
    source.ForEach(x=>x.DoSomething());
  }
}
于 2013-11-11T16:47:22.487 に答える
0

Linq メソッド呼び出しCast<T>を使用して、リストを正しい型に変換できます

public void DoSomethingWithAllMyTypes(IAllMyTypes allMyTypes)
{
    foreach (PropertyInfo propertyInfo in allMyTypes.GetType().GetProperties())
    {
        var x = propertyInfo.GetValue(allMyTypes) as IEnumerable
        if(x==null) throw new Exception("still wrong");

        DoSomething(x.Cast<MyDataObject>());
    }
}  
于 2013-11-11T17:44:24.313 に答える