In a method invocation (§7.5.5.1) of one of the forms
在下列形式的方法调用中
expr . identifier ( )
expr . identifier ( args )
expr . identifier < typeargs > ( )
expr . identifier < typeargs > ( args )
if the normal processing of the invocation finds no applicable methods, an attempt is made to process the construct as an extension method invocation. The objective is to find the best type-name C, so that the corresponding static method invocation can take place:
如果正常的调用流程没有找到适用的方法,则尝试将语言构造处理为扩展方法调用。目标是找到最佳类型名称C,使得(与方法调用构造)对应的(C上的)静态方法能够进行如下替代:
C . identifier ( expr )
C . identifier ( expr , args )
C . identifier < typeargs > ( expr )
C . identifier < typeargs > ( expr , args )
The search for C proceeds as follows:
C的搜索循序如下:
· Starting with the closest enclosing namespace declaration, continuing with each enclosing namespace declaration, and ending with the containing compilation unit, successive attempts are made to find a candidate set of extension methods:从包含调用构造的最近的命名空间声明开始,依次经过其父命名空间,父命名空间的父命名空间,直到整个编译单元,连续尝试查找候选扩展方法集合:
o If the given namespace or compilation unit directly contains non-generic type declarations Ci with extension methods Mj that have the name identifier and are accessible and applicable with respect to the desired static method invocation above, then the set of those extension methods is the candidate set.如果给定的命名空间或编译单元直接包含若干非泛型类型声明Ci,并且Ci上的扩展方法集合Mj匹配调用构造,那么这些扩展方法构成一个候选集合。匹配是指:方法名称同被调用方法名称相同;方法可访问;expr静态类型匹配扩展方法的this参数。
o If namespaces imported by using namespace directives in the given namespace or compilation unit directly contain non-generic type declarations Ci with extension methods Mj that have the name identifier and are accessible and applicable with respect to the desired static method invocation above, then the set of those extension methods is the candidate set.对于给定的命名空间或编译单元,如果通过using指令导入的命名空间中包含若干非泛型类型声明Ci,并且Ci上的多个扩展方法匹配正被解析的调用构造,那么这些扩展方法构成一个候选集合。
/*
这一部分描述的是候选扩展方法集合的搜索顺序。从内向外遍历ns直到cu,在处理每个ns/cu时先查找其中定义的类型,在查找导入的类型。目标类型当然不必是在本编译单元中定义的,可以是被引用程序集中的类型。
虽然上面将扩展方法所在类型称为“非泛型类” ,但实际上应该是非泛型静态类。
候选扩展方法集合中的所有元素都始终是同一类型的成员。
这组规则实际上是定义了static class上的扩展方法的优先级。
*/
· If no candidate set is found in any enclosing namespace declaration or compilation unit, a compile-time error occurs. 如果没有发现任何候选集合则产生编译错误。
· Otherwise, overload resolution is applied to the candidate set as described in (§7.4.3). If no single best method is found, a compile-time error occurs.否则,重载决策将应用于候选集合,如果没有找到最佳匹配,将发生编译时错误。
/*
这句话也是有问题的。如果重载决策失败,将查找下一个候选扩展方法集合,而不是直接发生编译错误。
如果在同一优先级有多个候选集合匹配,则发上调用不明确的编译错误。
*/
· C is the type within which the best method is declared as an extension method.称C是最佳方法的包含类型。
Using C as a target, the method call is then processed as a static method invocation (§7.4.4).把方法调用转换为C的静态方法调用。
The preceding rules mean that instance methods take precedence over extension methods, that extension methods available in inner namespace declarations take precedence over extension methods available in outer namespace declarations, and that extension methods declared directly in a namespace take precedence over extension methods imported into that same namespace with a using namespace directive. For example:上述规则意味着实例方法优先于扩展方法;在内层命名空间的扩展方法优先于外层命名空间中的扩展方法,直接在命名空间中定义的中的扩展方法优先于通过using导入的扩展方法。
参考:《C# 3.0 specification》