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

您可以使用 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 回答
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 回答