【发布时间】:2018-07-22 23:52:47
【问题描述】:
我一直在努力解决这种情况。我在 SO 上浏览过的各种类似(但不完全相同)的问题并没有完全引导我到我想要的地方。
我有一个Type 和一个Func<string, (bool, T)> 类型的对象,其中T 匹配Type。我希望能够通过反射或其他方式调用它的Invoke 方法。
我在运行时有一些Type:
Type type;
我在内存中有Func,但作为object:
object func;
func 的底层类型是我之前描述的。例如,如果type 代表DateTime,那么func 的基础类型将是:
Func<string, (bool, DateTime)>
但是type 在运行时可以是任何东西,所以如果它是一个int,那么func 现在将是一个
Func<string, (bool, int)>
如何使用在运行时具有正确类型这一事实来调用我的函数?我假设我必须使用某种反射,但对它的理解还不够好,无法开始。
非常感谢任何帮助。
总的来说,我对反射很陌生,但我发现它非常有趣,而且对于某些事情来说非常困难。如果您有任何关于阅读的建议或任何其他关于如何更好地学习反思的建议,那也太好了!
编辑/更新经过深思熟虑:
使用dynamic 并以这种方式调用 Invoke 会更好吗?看起来它可以正常工作,但随之而来的问题是,为什么你会经历更困难或更长时间的设置反射来调用某些东西的过程,而不是简单的动态调用。
无论如何,我仍然想知道如何使用反射来工作,看看会很有趣
【问题讨论】:
-
您必须使用两次反射,一次调用方法,一次(技术上两次)从元组中提取值。您可以按类型“缓存”所有这些反射,但不清楚您想如何使用
(bool, int)(因为您想使用它,对吗?)。通过使用动态,您无法“缓存”反射,因此每次都会产生发现和动态调用的全部成本。通过使用Tuple<>而不是ValueTuple<>,您可以跳过方法调用的反射,因为Func<string, object>将接受任何Func<string, Tuple<*>> -
其他解决方案是使用
Action<string, out bool, out something>之类的签名(稍微复杂一点,但我的意思应该很清楚)...现在您需要使用单个反射来调用方法。所有这些解决方案都是可能的......但你必须知道你想要哪一个。 -
I 将使用的解决方案是将方法的签名更改为
Func<string, (bool, object)>。该方法对第二个返回值进行装箱。没有反射,简单的代码。最后,返回(bool, TSomething)的方法已经是“自定义”的东西,所以我认为将其更改为(bool, object)以简化代码没有任何问题。