请参阅下面 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)”的类型参数。尝试明确指定类型参数。
最佳答案
MyAction
和 new Action(MyAction)
之间没有区别(当它们都有效时),只是前者在 C# 1 中不起作用。这是隐式方法组转换
。有时这是不适用的,最值得注意的是当编译器无法计算出您想要哪种委托(delegate)时,例如
Delegate foo = new Action(MyAction); // Fine
Delegate bar = MyAction; // Nope, can't tell target type
这在您的问题中发挥了作用,因为所涉及的两种方法都已重载。这基本上会导致头痛。
至于泛型方面 - 这很有趣。方法组并没有从 C# 3 类型推断中得到太多的爱——我不确定这是否会在 C# 4 中得到改进。如果您调用泛型方法并指定类型参数,类型推断工作得很好 - 但如果您尝试以相反的方式进行,它会失败:
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 非常有用)但在其他一些情况下会失败。在理想情况下,它会变得更容易理解并且在未来的版本中会更强大......我们拭目以待!
关于c# - 隐式和显式委托(delegate)创建之间的区别(有和没有泛型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/863688/