如何使用反射将每个“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);
}
答案 0 :(得分:2)
如果要使用反射,也可以使用反射调用辅助方法:
您必须获取MethodInfo
到泛型方法并创建一个通用方法反射句柄,以实际Invoke
该方法。在这种情况下,需要在运行时获取泛型方法的类型T
。
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 {
}
答案 1 :(得分: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());
}
}
答案 2 :(得分: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>());
}
}