Ere*_*rez 7 c# lambda delegates tuples predicate
我知道编译器可以从lambda表达式转换为Predicate.
例如:
Predicate<int> p = x => true;
Run Code Online (Sandbox Code Playgroud)
很好.
但是当我想创建一个包含谓词的元组时.我试着这样做(简化版):
Tuple<Predicate<int>> t;
t = Tuple.Create(x => true);
Run Code Online (Sandbox Code Playgroud)
我收到了编译错误:
无法从用法推断出方法'System.Tuple.Create(T1)'的类型参数.尝试显式指定类型参数.
我的问题是这是一个错误,这里的歧义在哪里?
(我知道我可以通过强制转换修复它:t = Tuple.Create((Predicate<int>)(x => true));
但是我想理解为什么第一种方式不好,而且我也不想进行转换以节省输入:)
这里含糊不清哪里?
这里的歧义是编译器不会尝试推断传递给Tuple.Create基于已经声明所需类型的左侧的lambda表达式.会发生什么样的类型推断算法(无论你声明变量的类型),并且找不到与lambda表达式匹配的合适匹配,因为它没有足够的信息.
通过声明元组的类型并明确告诉编译器如何推断lambda表达式,可以很容易地解决这个问题:
t = Tuple.Create<Predicate<int>>(x => true);
Run Code Online (Sandbox Code Playgroud)
如果您想进入类型推断算法并查看它失败的原因:
鉴于:
Tr M<X1…Xn>(T1 x1 … Tm xm)
Run Code Online (Sandbox Code Playgroud)
通过形式M(E1 ... Em)的方法调用,类型推断的任务是为每个类型参数X1 ... Xn找到唯一类型参数S1 ... Sn,使得调用M(E1 ... Em)变为有效.
现在我们开始:
7.5.2.1第一阶段:
对于每个方法参数Ei:
如果Ei是匿名函数,则从Ei到Ti进行显式参数类型推断(第7.5.2.7节)
所以我们看一下显式参数类型推断的作用:
7.5.2.7显式参数类型推断
通过以下方式从表达式E到类型T进行显式参数类型推断:
·如果E是具有参数类型U1 的显式类型匿名函数 ... Uk和T是具有参数类型V1 ... Vk的委托类型或表达式树类型,则对于每个Ui,从Ui到ui进行精确推断(第7.5.2.8节)相应的Vi.
您的匿名函数不是显式类型,因此编译器无法从参数类型Ui..Uk进行精确推断到正确的重载Tuple.Create.