编译时未知类型的嵌套委托调用
nested delegate call of unknown type at compile time
假设我有 2 个委托,并且我在编译时不知道“TUnknown”类型
Func<T, TUnknown> delegate1;
Func<TUnknown, object> delegate2;
如何创建这样的 lambda 语句:
(T t) => ((Func<TUnknown, object>)delegate2)(((Func<T, TUnknown>)delegate1)(t))
我可以像这样使用 DynamicInvoke 做到这一点:
(T t) => delegate2.DynamicInvoke(delegate1.DynamicInvoke(t));
但是很慢。有更好的解决方案吗?
完整代码
static Func<T, object> PropertySerializerFactory(PropertyInfo property1)
{
var delegate1 = property1.GetMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(property1.DeclaringType, property1.PropertyType));
//Just a function that get a specific type of property
//property2 is a property of the class property1
PropertyInfo property2 = GetFilteredProperties(property1.PropertyType);
var delegate2 = property2.GetMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(property1.PropertyType, property2.PropertyType));
return (T t) => delegate2.DynamicInvoke(delegate1.DynamicInvoke(t));
}
有两种方法可以解决这个问题。第一个选项,将尽可能多的工作转移到通用方法中;
static Func<T,object> GetFunc<T,U>(PropertyInfo prop1, PropertyInfo prop2){
var getProp1 = property1.GetMethod.CreateDelegate<Func<T,U>>();
var getProp2 = property2.GetMethod.CreateDelegate<Func<U,object>>();
return (T t) => getProp2(getProp1(t));
}
然后,一旦您了解了运行时 Type
,您就可以制作正确的工厂方法通用版本并调用它。
var method = typeof(...).GetMethod(nameof(GetFunc));
method = method.MakeGenericMethod(new Type[]{ type1, type2 });
return method.Invoke(null, new object[]{ prop1, prop2 });
第二个选项是构建一个 Expression
树并编译它。
假设我有 2 个委托,并且我在编译时不知道“TUnknown”类型
Func<T, TUnknown> delegate1;
Func<TUnknown, object> delegate2;
如何创建这样的 lambda 语句:
(T t) => ((Func<TUnknown, object>)delegate2)(((Func<T, TUnknown>)delegate1)(t))
我可以像这样使用 DynamicInvoke 做到这一点:
(T t) => delegate2.DynamicInvoke(delegate1.DynamicInvoke(t));
但是很慢。有更好的解决方案吗?
完整代码
static Func<T, object> PropertySerializerFactory(PropertyInfo property1)
{
var delegate1 = property1.GetMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(property1.DeclaringType, property1.PropertyType));
//Just a function that get a specific type of property
//property2 is a property of the class property1
PropertyInfo property2 = GetFilteredProperties(property1.PropertyType);
var delegate2 = property2.GetMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(property1.PropertyType, property2.PropertyType));
return (T t) => delegate2.DynamicInvoke(delegate1.DynamicInvoke(t));
}
有两种方法可以解决这个问题。第一个选项,将尽可能多的工作转移到通用方法中;
static Func<T,object> GetFunc<T,U>(PropertyInfo prop1, PropertyInfo prop2){
var getProp1 = property1.GetMethod.CreateDelegate<Func<T,U>>();
var getProp2 = property2.GetMethod.CreateDelegate<Func<U,object>>();
return (T t) => getProp2(getProp1(t));
}
然后,一旦您了解了运行时 Type
,您就可以制作正确的工厂方法通用版本并调用它。
var method = typeof(...).GetMethod(nameof(GetFunc));
method = method.MakeGenericMethod(new Type[]{ type1, type2 });
return method.Invoke(null, new object[]{ prop1, prop2 });
第二个选项是构建一个 Expression
树并编译它。