注意
本文是特性规范。 该规范充当该功能的设计文档。 它包括建议的规范更改,以及功能设计和开发过程中所需的信息。 这些文章将发布,直到建议的规范更改最终确定并合并到当前的 ECMA 规范中。
功能规范与已完成的实现之间可能存在一些差异。 这些差异记录在相关的 语言设计会议(LDM)笔记中。
可以在 规范一文中详细了解将功能规范采用 C# 语言标准的过程。
支持者问题:https://github.com/dotnet/csharplang/issues/7429
总结
此建议通过多种方式优化方法组的自然类型的确定:
- 逐个范围考虑候选方法(首先是实例方法,然后是每个范围内的扩展方法)
- 修剪那些没有成功机会的候选项,这样他们就不会干扰确定唯一的签名:
- 如果未提供类型参数(
var x = M;
),则删除泛型实例方法 - 根据可减少扩展的能力和约束条件来修剪泛型扩展方法
- 如果未提供类型参数(
方法组自然类型的上下文
在 C# 10 中,方法组获得了弱的自然类型。
该类型是一种“弱类型”,因为它仅在方法组不是目标类型(即它在 System.Action a = MethodGroup;
中没有作用)时才起作用。
这种弱自然类型可能出现 var x = MethodGroup;
等情况。
如果方法组中的所有候选方法都具有通用签名,则方法组具有自然类型。 (如果方法组可能包含扩展方法,则候选项包括包含类型和所有扩展方法范围。
在实践中,这意味着我们:
- 构造所有候选方法集:
- 相关类型的方法位于集中(如果它们是静态的,并且接收方是一种类型,或者它们是非静态的,并且接收方是值)
- 可以缩减的扩展方法(在所有范围内)属于该集合。
- 如果所有候选项的签名不匹配,则方法组没有自然类型
- 如果生成的签名的 arity 与所提供的类型参数的数目不匹配,则方法组没有自然类型
- 否则,生成的签名将用作自然类型
建议
原则是逐个范围地仔细筛选候选对象,尽早去除那些我们已知不可能成功的候选者,这就是重载解析中使用的相同原则。
- 对于每个范围,我们将构造一组所有候选方法:
- 对于初始范围,如果相关类型的方法是静态的,并且接收者是类型;或者如果它们是非静态的,并且接收者是值,则这些方法与提供的类型参数基本匹配,并且使用提供的类型参数满足约束,则这些方法都在集合中
- 对于后续作用域,该作用域中的扩展方法可以用提供的类型参数替换,并在满足约束条件的同时使用接收器的值进行缩减
- 如果在给定范围内没有候选项,请转到下一个范围。
- 如果所有候选项的签名不匹配,则方法组没有自然类型
- 否则,生成的签名将用作自然类型
- 如果范围已用尽,则方法组没有自然类型
与逐范围建议相关:https://github.com/dotnet/csharplang/issues/7364 与更好地处理通用扩展方法的建议相关:https://github.com/dotnet/roslyn/issues/69222