【发布时间】:2020-12-24 04:14:35
【问题描述】:
考虑以下代码,其中 C# 可以根据提供的隐式类型 Action
我很惊喜,意识到我已经“不假思索地依赖这种方便的行为”有一段时间了,尽管它要求编译器检查 Action 中的代码以及有效的目标站点类型。通常,类型必须在在目标表达式中使用之前解析。
这种行为是什么时候引入的?这种类型推断的正确名称是什么?有哪些限制和已知的极端情况?哪些文档链接(或规范中的部分)涵盖了该行为?
static void WithAction(Action<string> s) {
Console.WriteLine("string action");
s("string");
}
static void WithAction(Action<int> i) {
Console.WriteLine("int action");
i(1);
}
void Main()
{
// Compiler has to INFER that this is an Action<string>
// where the target type must be in {Action<string>, Action<int>}
// (int does not have a Length property)
WithAction(s => Console.WriteLine(s.Length == 1));
// Ditto, except compiler infers Action<int>.
// (there is no string == int operator overload)
WithAction(i => Console.WriteLine(i == 1));
// compiler error
// CS0121 The call is ambiguous between the following methods or properties:
// 'UserQuery.WithAction(Action<string>)' and 'UserQuery.WithAction(Action<int>)'
// (there is both int == int and string == string!)
// WithAction(z => Console.WriteLine(z == z));
}
代码在 LINQPad 5 中运行并产生以下输出:
string action
False
int action
True
【问题讨论】:
-
Jon Skeet 写了一篇很棒的博文,可能会帮助您找到一些答案:codeblog.jonskeet.uk/2010/10/28/…
-
@DavidL 感谢您的链接。但是,它似乎没有涵盖这种情况。在上面,它没有在例如之间决定。
Action<T>(更具体)和Action,它在Action<string>和Action<int>之间做出决定,其中必须“尝试编译”作为目标类型的操作以查看它们是否可以 匹配一个 XOR 其他重载方法。我已经包含了非编译情况,当方法的主体 not 足以让编译器推断 Action 的参数是stringXOR @ 987654329@(因此 Action 必须是Action<string>或Action<int>)。
标签: c# syntax overloading type-inference type-systems