【问题标题】:How to create an Action<T> form an object method given via Reflection?如何从通过反射给出的对象方法创建 Action<T>?
【发布时间】:2015-03-27 06:01:48
【问题描述】:

我有一个void SubscribeToPublish&lt;TMessage&gt;(Action&lt;TMessage&gt; action) 方法。它需要一个Action&lt;T&gt;。我有一个纯粹从Type 创建的对象,方式如下:

var Node =  Activator.CreateInstance(type);
var methods = type.GetMethods(BindingFlags.Public).Where(methodInfo => methodInfo.GetParameters().Count() == 1).ToList();
methods.ForEach(methodInfo => {
    SubscribeToPublish(o => methodInfo.Invoke( pair.Value.Node, o )); // Here I see error cannot be inferred from usage.
});

因此我想知道:如何通过反射创建对象在旅途中创建Action&lt;T&gt;

【问题讨论】:

  • 你能提供错误信息和堆栈跟踪吗?
  • 你的错误是发生在编译时还是运行时?我猜你应该使用 (TMessage msg) => methodInfo.Invoke(pair.Value.Node, msg)
  • 必须通过反射吗? Linq 表达式编译呢?
  • 顺便说一句。鉴于您正在检查 methodInfo.GetParameters().Count() == 1,委托必须是 Action&lt;T1, T2&gt;,因为您需要调用的对象和方法的参数。

标签: c# .net generics reflection lambda


【解决方案1】:

methodInfo.Invoke 接受任意对象参数。因此,编译器无法推断您指的是哪个具体的 TMessage 类型。

解决方案是明确指定:

SubscribeToPublish((MyMessage o) => methodInfo.Invoke(pair.Value.Node, 
                                                      new object[] {o}));

【讨论】:

  • SubscribeToPublish&lt;MyMessage&gt;(o=&gt;...) :-)
  • 主要问题是我们动态调用的方法的对象类型未知=(
  • @DuckQueen:在这种情况下,如果SubscribeToPublish 的逻辑不依赖于TMessage 的实际类型,SubscribeToPublish((object o) =&gt; ...) 将是一个选项。
  • 而下一个问题是它确实如此=(
  • @DuckQueen:那么泛型是问题的错误解决方案。通用信息是静态类型的,也就是说,它需要在编译时知道。对于您的问题,执行 运行时类型检查 的非泛型方法可能更适合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多