无法从'方法组'转换为'System.Action <object>'错误

Jon*_*han 45 c# generics delegates method-group

我创建了以下函数:

public void DelegatedCall(Action<Object> delegatedMethod)
Run Code Online (Sandbox Code Playgroud)

并定义了以下方法

public void foo1(String str) { }
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试打电话DelegateCallfoo1:

DelegatedCall(foo1);
Run Code Online (Sandbox Code Playgroud)

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

Argument 1: cannot convert from 'method group' to 'System.Action<object>'

这个错误的原因是什么,我该如何纠正?不幸的是,铸造foo1Action是不是一种选择.

Cod*_*aos 29

DelegatedCall期望一个代理人将任何一个object作为参数.但是你foo1传递的功能DelegatedCall只能应付一个string论点.因此,转换不是类型安全的,因此是不可能的.

输入参数是反式变量,但您的代码需要协方差.(参见协方差和反差的区别.)

你可以制作DelegatedCall通用的:

DelegatedCall<T>(Action<T> action)
Run Code Online (Sandbox Code Playgroud)

......或者让任何代表:

DelegatedCall(Delegate action)
Run Code Online (Sandbox Code Playgroud)

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

  • 你能把它变成通用的吗? (4认同)
  • 您知道我可以创建这样的代码吗?我希望 DelegateCall 能够接收一个函数,该函数接收任何类型的任何一个参数(String、bool、List...) (2认同)
  • 您能推荐有关如何使用反射来实现第二个选项的阅读材料吗? (2认同)

Mar*_*ell 10

差异并非如此; 你需要的

DelegatedCall(obj => foo1((string)obj));
Run Code Online (Sandbox Code Playgroud)

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

请注意,如果它是foo1(object)Action<string>(即反过来)它可能会工作(在4.0中),因为每个字符串都是一个对象.