[英]How can I use reflection to pass each list of “MyTypes” to a generic method with a constraint of T:MyType?
如何使用反射将每个“ 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);
}
如果要使用反射,则也可以使用反射来调用辅助方法:
您将必须获取通用方法的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 {
}
我正在努力寻找一个案例,在这种情况下,您需要以与过去相同的方式来构造数据,而又不会使事情复杂化。 如果您发现合法案件,请发表评论,我将更新答案以反映您的需求。
你可以用你的基类开始,使它抽象,把一个抽象的方法,它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());
}
}
您可以使用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>());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.