编译时未知类型的嵌套委托调用

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 树并编译它。