【问题标题】:How to pass an arbitrary method (or delegate) as parameter to a function?如何将任意方法(或委托)作为参数传递给函数?
【发布时间】:2013-04-02 14:47:48
【问题描述】:

我需要能够将任意方法传递给某个函数myFunction

void myFunction(AnyFunc func) { ... }

应该可以使用其他静态、实例、公共或私有方法甚至委托来执行它:

myFunction(SomeClass.PublicStaticMethod);
myFunction(SomeObject.PrivateInstanceMethod);
myFunction(delegate(int x) { return 5*x; });

传递的方法可以有任意数量的参数和任意返回类型。还应该可以通过反射了解myFunction 中参数的实际数量及其类型。 myFunction 定义中的 AnyFunc 是什么来满足此类要求?可以有多个 myFunction 的重载版本。

【问题讨论】:

  • 如果方法有参数,你希望传递什么?听起来您应该将任何方法转换为无参数/无效返回(又名Action),然后再将其传递给此方法。
  • myFunction 将分析函数的参数,根据一些外部数据库检查它们并使用必要的值调用它,如果在数据库中没有找到匹配的条目,则调用它。
  • 这是一个非常令人担忧的设计,您实际上将代码视为数据。您应该考虑尝试重新设计它,使您的代码是静态的。
  • 是的。将嵌入一个编译器,该编译器将从数据构造代码。我知道安全风险,但这是我们项目中需要的。
  • @Hi-Angel 处理已知签名的方法。拥有一个接受字符串并返回特定类型结果的未知函数,而不知道它的实现,这当然不是糟糕的设计。

标签: c# delegates argument-passing


【解决方案1】:

让方法接受Delegate,而不是特定的委托:

void myFunction(Delegate func)
{

}

【讨论】:

  • 正如 cdhowie 的回答一样,它需要将委托转换为特定委托类型或 Func<...>。我想避免这种情况。
  • @SergiyByelozyorov 正如他告诉你的那样,这是不可能的。
【解决方案2】:

Delegate 类型是所有其他委托类型的超类型:

void myFunction(Delegate func) { ... }

然后,func.Method 会给你一个MethodInfo 对象,你可以使用它来检查返回类型和参数类型。

调用函数时,您必须明确指定要创建的委托类型:

myFunction((Func<int, int>) delegate (int x) { return 5 * x; });

对您要在更高级别上完成的工作有所了解会很好,因为这种方法可能并不理想。

【讨论】:

  • 我想让调用站点尽可能简单,并在库中隐藏细节。有什么方法可以指定myFunction,这样用户就不需要投射他们的代表了?
  • @SergiyByelozyorov 调用站点不可能再简单了,因为编译器需要一些具体的委托类型来创建一个实例。如果你想接受“任何委托类型”,那么调用者必须自己指定一个委托类型。 (例如,给定匿名委托delegate () { }ActionThreadStart 都是兼容的委托类型——编译器如何知道要创建哪一个?)
  • 谢谢。我想这就是我的答案。那是不可能的。谢谢。
  • 但是为什么编译器需要知道确切的委托类型呢?仅仅知道委托语法中指定的参数类型还不够吗?返回值类型有问题吗?编译器不能从正文中派生出来吗?
  • @Harb (Func&lt;int, int&gt;) 是对委托类型的强制转换。这为编译器提供了足够的上下文来推断匿名委托的类型应该是Func&lt;int, int&gt;
猜你喜欢
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多