我有一个开放泛型类型属性的PropertyInfo,通过以下方式获得:
public interface ITest<T>
{
T Item { get; }
}
var propertyInfo = typeof(ITest<>).GetProperty("Item");
我希望能够创建一个具体的,可调用的委托,从Func<ITest<int>, int>
填写类类型参数(例如propertyInfo
)。
显而易见的是propertyInfo.GetMethod.MakeGenericMethod(typeof(int)).CreateDelegate(...)
,但由于GetMethod
不是通用的,因此失败,因为它是通用类的属性。
我知道您可以通过将类型参数应用于之前的类型(例如typeof(ITest<int>).GetProperty("Item").GetMethod.CreateDelegate(...)
)来获取此属性的委托,但我希望只需要在ITest
中查找该属性一旦,因为它将为每个类型参数重复相同的搜索。
有没有办法创建此委托,或者只能通过使用typeof(ITest<int>)
来开始?
短版
以下TestMethod
可以通过CreateGetter
的某些实现(假设T::Equals
明智地实施)来通过吗?
public void TestMethod<T>(ITest<T> x)
{
var propertyInfo = typeof(ITest<>).GetProperty("Item");
var getter = CreateGetter<int>(propertyInfo);
Assert(getter(x).Equals(x.Item));
}
答案 0 :(得分:0)
如果您确实想使用PropertyInfo
,此方法将起作用:
public static Func<Test<T>, T> CreateGetter<T>(PropertyInfo info)
{
Type type = info.ReflectedType;
PropertyInfo genericProperty = type.MakeGenericType(typeof(T)).GetProperty(info.Name);
return (source) => (T)genericProperty.GetValue(source);
}
否则我会建议:
public static Func<Test<T>, T> GetGenericPropertyDelegate<T>(string propertyName)
{
PropertyInfo genericProperty = typeof(Test<>).MakeGenericType(typeof(T)).GetProperty(propertyName);
return (source) => (T)genericProperty.GetValue(source);
}
用法:
public void Test<T>(ITest<T> x)
{
var getter = GetGenericPropertyDelegate<int>("Item");
Assert(getter(x).Equals(x.Item));
}
答案 1 :(得分:0)
您需要先实例化泛型类型,然后才能以通常的方式从MethodInfo
创建委托。
var target = typeof(ITest<>).MakeGenericType(typeof(int));
var prop = target.GetProperty("Item");
var dlg = prop.GetMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(target, prop.PropertyType));