我有这两种方法:
string Foo<T>(Func<T, string> f) => throw new NotImplementedException();
string Bar(int x) => x.ToString();
为什么我可以在 C# 中将一个方法分配给一个变量,然后将该变量传递给一个方法:
var f = Bar;
Foo(f); // compiles just fine
但不直接传方法?
Foo(Bar);
这会产生编译错误
无法从用法中推断出方法“Program.Foo(Func
)”的类型参数。尝试显式指定类型参数。
为什么变量赋值可以推断类型,而实参赋值却不能推断类型?
编辑:
具体来说,细微的区别在于方法组是 被认为可以仅根据以下条件转换为委托类型 参数是否匹配,而不是还基于是否 返回类型匹配。 Lambdas 检查参数和返回值 类型。
如果使用类型推断,委托的参数类型为 在推理过程中用作参数类型。返回类型为 委托不用于推理
但这与 C# 编程指南和委托冲突:
从 C# 10 开始,具有单个重载的方法组具有 自然型。这意味着编译器可以推断返回类型并 委托类型的参数类型:
var read = Console.Read;
这意味着编译器确实能够将一组方法转换为委托。那么直接传递方法组时为什么不做同样的事情呢?
var f = Bar
将隐式创建一个指向 Bar 的 Delegate。您可以立即将 Bar
声明为委托,它将起作用。见下文。
using System;
public class Program
{
public static void Main()
{
string Foo<T>(Func<T, string> f) => throw new NotImplementedException();
Func<int, string> Bar = x => x.ToString();
var f = Bar;
Foo(f); // compiles just fine
Foo(Bar); // also compiles
}
}