问题描述
请看下面 Go() 方法中的四行代码:
delegate void Action<T>(T arg);
delegate void Action();
void DoSomething<T>(Action<T> action)
{
//...
}
void DoSomething(Action action)
{
//...
}
void MyAction<T>(T arg)
{
//...
}
void MyAction()
{
//...
}
void Go<T>()
{
DoSomething<T>(MyAction<T>); // throws compiler error - why?
DoSomething(new Action<T>(MyAction<T>)); // no problems here
DoSomething(MyAction); // what's the difference between this...
DoSomething(new Action(MyAction)); // ... and this?
}
请注意,第一次调用产生的编译器错误是:方法Action(T)"的类型参数不能从用法中推断出来.尝试明确指定类型参数.
Note that the compiler error generated by the first call is: The type arguments for method 'Action(T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
推荐答案
MyAction
和 new Action(MyAction)
没有区别(当它们都有效时)除了前者之外,在 C# 1 中不起作用.这是一个隐式方法组转换
.有时这不适用,尤其是当编译器无法确定您想要什么样的委托时,例如
There's no difference between MyAction
and new Action(MyAction)
(when they're both valid) other than the former won't work in C# 1. This is an implicit method group conversion
. There are times that this isn't applicable, most notable when the compiler can't work out what kind of delegate you want, e.g.
Delegate foo = new Action(MyAction); // Fine
Delegate bar = MyAction; // Nope, can't tell target type
这在您的问题中起作用,因为所涉及的两种方法都已重载.这基本上会导致头痛.
This comes into play in your question because both of the methods involved are overloaded. This leads to headaches, basically.
至于泛型方面 - 这很有趣.方法组并没有从 C# 3 类型推断中得到太多的喜爱——我不确定这是否会在 C# 4 中得到改进.如果您调用泛型方法并指定类型参数,则类型推断工作得相当好 - 但如果您尝试反过来做,它会失败:
As for the generics side - it's interesting. Method groups don't get much love from C# 3 type inference - I'm not sure whether that's going to be improved in C# 4 or not. If you call a generic method and specify the type argument, type inference works fairly well - but if you try to do it the other way round, it fails:
using System;
class Test
{
static void Main()
{
// Valid - it infers Foo<int>
DoSomething<int>(Foo);
// Valid - both are specified
DoSomething<int>(Foo<int>);
// Invalid - type inference fails
DoSomething(Foo<int>);
// Invalid - mismatched types, basically
DoSomething<int>(Foo<string>);
}
static void Foo<T>(T input)
{
}
static void DoSomething<T>(Action<T> action)
{
Console.WriteLine(typeof(T));
}
}
C# 3 中的类型推断非常复杂,在大多数情况下都能很好地工作(特别是它对 LINQ 非常有用),但在其他一些情况下却失败了.在理想的世界中,它会变得更容易理解并且在未来的版本中会更强大......我们拭目以待!
Type inference in C# 3 is very complicated, and works well in most cases (in particular it's great for LINQ) but fails in a few others. In an ideal world, it would become easier to understand and more powerful in future versions... we'll see!
这篇关于隐式和显式委托创建之间的区别(有和没有泛型)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!