【问题标题】:How to get the arguments from an Action?如何从动作中获取参数?
【发布时间】:2015-11-09 14:22:33
【问题描述】:

我有一个方法可以接受带有如下签名的动作:

public void DoSomething(Action code); 

那么我会这样称呼这个方法:

DoSomething(()=> CallSomething("A","B","C"); 

在 DoSomething 方法中,如何获取参数值?

要考虑的另一件事是 CallSomething 可能具有可选参数,这意味着我不能只将 DoSomething 的签名更改为 -> Expression<Action>

我需要做的就是获取参数值,我对任何可行的方法都感兴趣。

我已经尝试创建一个接受Expression<Action> 的新方法,然后通过(来自 DoSomething)传递操作,但没有填充参数。

欢迎提出任何建议。

【问题讨论】:

  • 我认为这不会很简单,因为在DoSomething 函数中,code 只是某种函数指针;你并不总是知道它是一个调用另一个函数的 lambda。我觉得你必须使用反射来反汇编 lambda 并查找函数调用,但即便如此你也在做一些相当恶心的事情。
  • 为什么?你想做什么,为什么你认为采用Action(或Expression<Action>)的方法是这样做的?为什么Expression<Action> 会阻止您使用可选参数?

标签: c#


【解决方案1】:

重点是你不想

您的方法接受Action 委托。它的意思是“我只想调用一些没有参数且没有返回值的东西”。

如果您需要向函数传递参数,请使用不同的委托,或者直接将它们作为参数传递。

想想这个没有 lambda。你有一个接口,它有一个方法,Act,它不带参数也不返回值。

DoSomething(IMyInterface myInterface)
{
  myInterface.Act(); // How do I get the arguments of some method that `Act` calls?
}

这有任何意义吗?您是否希望能够反汇编在myInterface 中传递的整个实例,找到它的Act 方法,检查从那里调用的所有方法并截取它们的参数?委托只是一个带有一点状态的单方法接口。

如果您需要参数,让它们成为公共接口的一部分。否则,您的抽象没有任何意义,您不应该使用它。没有人强制您使用 lambda,也没有人强制您传递单个 lambda 且没有参数,也没有人强制您使用Action 特别是。它们都是简单的工具 - 如果它们不适合您的任务,不要使用它们

更直接地回答你的问题:你得到的论点与任何其他论点一样。问题是您的操作没有参数

【讨论】:

  • 你能给我穷人版吗?即:我正在传递可以执行的代码,对吗?因为它可以被执行,所以它在某些时候可以理解参数。那我怎样才能得到论点呢?
  • @JL。你没有传递 code - 你传递的是一个接口。当然,实现该接口的类确实有代码,但是在调用DoSomething 方法时,该代码已经编译。即使通过反射,也无法获得 C# 代码 - 您能做的最好的事情就是以某种方式解释 IL 代码。也许它们甚至不再是参数(例如,调用可能已被内联)!如果您需要检查逻辑代码,请使用Expression<Action>。即使这样,也很难以任何有意义的方式解释数据。 你想做什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-20
  • 1970-01-01
  • 2018-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多