3 回答
TA贡献1719条经验 获得超6个赞
Test(A);
之所以失败,是因为唯一适用的方法(Test<T>(Action<T>))需要类型推断,并且类型推断算法要求每个每个参数都属于某种类型或为匿名函数。(从类型推断算法的规范(第7.5.2节)中推断出这一事实)方法组A不是任何类型(即使它可以转换为适当的委托类型),并且它不是匿名函数。
Test<string>(A);
这成功完成,区别在于绑定Test不需要类型推断,并且方法组A可转换为所需的委托参数type void Action<string>(string)。
Test((string a) => {});
这样成功了,区别在于类型推断算法在第一阶段(第7.5.2.1节)提供了匿名函数。匿名函数的参数和返回类型是已知的,因此可以进行显式的参数类型推断,从而在匿名函数(void ?(string))中的类型与Test方法的参数的委托类型((void Action<T>(T))。没有为与匿名函数的算法相对应的方法组指定算法。
Test((Action<string>)A);
这成功完成,区别在于未类型化的方法组参数A被强制转换为类型,从而允许类型推断Test以特定类型的表达式作为方法的唯一参数正常进行。
从理论上讲,我无法认为为什么无法在方法组上尝试重载解析A。然后,如果找到单个最佳绑定,则可以为方法组提供与匿名函数相同的处理。在这样的情况下尤其如此,即方法组仅包含一个候选项,并且没有类型参数。但是它在C#4中不起作用的原因似乎是没有设计和实现此功能的事实。鉴于此功能的复杂性,其应用的局限性以及三个简单的解决方法的存在,我不会为此而屏息!
TA贡献1828条经验 获得超13个赞
我认为这是因为有两步推断:
它必须推断出您要将A转换为通用委托
它必须推断委托参数的类型是什么
我不确定这是否是原因,但我的直觉是两步推断对于编译器而言不一定很容易。
编辑:
只是预感,但是有什么告诉我第一步是问题。编译器必须弄清楚要转换为具有不同数量的泛型参数的委托,因此无法推断参数的类型。
TA贡献1794条经验 获得超8个赞
在我看来,这似乎是一个恶性循环。
Test方法需要从泛型类型构造的委托类型参数Action<T>。您改为传入一个方法组:Test(A)。这意味着编译器必须将您的参数转换为委托类型(方法组转换)。
但是,哪种代表类型?要知道委托类型,我们需要知道T。我们没有明确指定它,因此编译器必须推断出它以找出委托类型。
要推断方法的类型参数,我们需要知道方法参数的类型,在这种情况下为委托类型。编译器不知道参数类型,因此失败。
在所有其他情况下,两种类型的参数都是显而易见的:
// delegate is created out of anonymous method,
// no method group conversion needed - compiler knows it's Action<string>
Test((string a) => {});
// type of argument is set explicitly
Test((Action<string>)A);
或明确指定类型参数:
Test<string>(A); // compiler knows what type of delegate to convert A to
- 3 回答
- 0 关注
- 584 浏览
添加回答
举报