【问题标题】:Cannot convert from 'method group' to 'System.Action<object>' error无法从“方法组”转换为“System.Action<object>”错误
【发布时间】:2011-01-16 09:55:31
【问题描述】:

我创建了以下函数:

public void DelegatedCall(Action<Object> delegatedMethod)

并定义了如下方法

public void foo1(String str) { }

但是,当我尝试用foo1 调用DelegateCall 时:

DelegatedCall(foo1);

...我收到以下编译器错误:

Argument 1: cannot convert from 'method group' to 'System.Action&lt;object&gt;'

此错误的原因是什么,我该如何纠正?不幸的是,将foo1 转换为Action 不是一种选择。

【问题讨论】:

标签: c# generics delegates method-group


【解决方案1】:

DelegatedCall 需要一个接受任何object 作为参数的委托。但是您传递给DelegatedCall 的函数foo1 只能处理string 参数。因此,转换不是类型安全的,因此是不可能的。

输入参数是contra-variant,但是你的代码需要covariance。 (见Difference between Covariance & Contra-variance。)

您可以将DelegatedCall 设为通用:

DelegatedCall<T>(Action<T> action)

...或者让它接受任何委托:

DelegatedCall(Delegate action)

但是实现它是丑陋的,需要反思。它也不验证函数在编译时是否只有一个参数。

【讨论】:

  • 你知道我有什么方法可以创建这样的代码吗?我希望 DelegateCall 能够接收一个函数,该函数接收任何类型的任何一个参数(字符串、布尔值、列表...)
  • 你能推荐任何阅读材料如何使用反射来实现第二个选项吗?
【解决方案2】:

方差不能这样解决;你需要

DelegatedCall(obj => foo1((string)obj));

即使在 4.0 中,它也不会相信每个对象都是字符串。

请注意,如果它是 foo1(object)Action&lt;string&gt;(即反过来),它可能会起作用(在 4.0 中),因为每个字符串 都是 一个对象。

【讨论】:

  • 反之亦然,甚至在 4.0 之前也能正常工作。即使在早期版本中也可以从方法组方差转换。
  • 好吧,无论如何我可以完成这项工作:我希望 DelegateCall 能够接收一个函数,该函数接收任何类型的任何一个参数(字符串、布尔值、列表......)。任何帮助将不胜感激
猜你喜欢
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 2021-06-25
  • 2013-10-02
  • 1970-01-01
  • 2015-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多