gpt4 book ai didi

c# - 编译器如何从 LAMBDA 表达式推断委托(delegate)类型?

转载 作者:行者123 更新时间:2023-11-30 15:21:12 27 4
gpt4 key购买 nike

示例代码

int id = 123;

ThreadPool.QueueUserWorkItem(state => ThreadEntryPoint((int)state), id);

public void ThreadEntryPoint(int uniqueId)
{
Console.WriteLine("uniqueId=" + uniqueId);
}

问题

从提供的 LAMBDA 表达式中,编译器如何知道它需要创建 QueueUserWorkItem(WaitCallback, AnObject) 的实例?

更具体地说:我知道它是在推断委托(delegate)类型。我不明白的是它通过什么决策树(从高层)来选择正确的委托(delegate)类型来实例化?

引用文献

最佳答案

How does compiler infer the delegate type from LAMBDA expression?

从根本上说,它没有。

编译器从名为 QueueUserWorkItem 的方法组中的可用重载推断委托(delegate)类型.只有两个重载,只有一个有两个参数,并且两个重载都使用委托(delegate)类型 WaitCallback .

因此,委托(delegate)类型必须WaitCallback .确定后,编译器可以将 lambda 表达式编译为匿名方法并实例化为 QueueUserWorkItem() 的参数。方法调用必要的委托(delegate)对象来调用该匿名方法。

在更复杂的情况下,编译器必须执行一些分析以确定重载的“最佳”匹配,并且该分析可能涉及 lambda 表达式,以消除基于 lambda 表达式的重载可能性.

但编译器绝不会从 lambda 表达式开始并直接转到委托(delegate)类型。对于要转换为委托(delegate)实例的 lambda 表达式,lambda 表达式需要一些其他上下文来确定所需的委托(delegate)类型,例如对类型化变量的赋值、显式强制转换或(如本例中)方法重载,其中使用 lambda 表达式的参数具有与 lambda 表达式兼容的特定委托(delegate)类型。

请注意,泛型方法仍然存在类型推断,其中 lambda 用于推断类型参数。 Eric Lippert's comment解释清楚:

There are some instances where the compiler must infer the constructed delegate type from the lambda. For example, if we have M<A, R>(Func<A, R> f) and M((string x) => x.Length) then the compiler will infer Func<string, something> first, from the lambda parameter, and then Func<string, int> from the body of the lambda.

我的观点是编译器不会推断出 Func<T, TResult>从头开始。正如 Eric 指出的那样,编译器确实使用 lambda 来推断类型参数,但编译器仍然需要已知开放泛型类型的上下文。

有关更多详细信息,您应该阅读 the C# specification .它将详细说明如何执行重载决策以及管理该决策和将 lambda 表达式与类型匹配的规则。

补充阅读:
.Net lambda expression— where did this parameter come from?
Why can't an anonymous method be assigned to var?
Why can't the compiler tell the better conversion target in this overload resolution case? (covariance)
Convert this delegate to an anonymous method or lambda
并非巧合的是,前三个包括 Eric Lippert 撰写的对该主题和相关问题的精彩讨论,他曾在 Visual Studio C# 编译器和语言设计团队工作。

关于c# - 编译器如何从 LAMBDA 表达式推断委托(delegate)类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38163285/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com