LinQ & Extension method invocations
От: Norex Россия  
Дата: 08.01.07 06:45
Оценка:
Возникли трудности в понимании спецификации, мог ли кто-то мне объяснить, что они хотели сказать следующим:
Источник: C# 3.0 Language Specification

26.2.3 Extension method invocations
The detailed rules for extension method invocation are described in the following. 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 instance methods (specifically, if the set of candidate methods for the invocation is empty), an attempt is made to process the construct as an extension method invocation. The method invocation is first rewritten to one of the following, respectively:
identifier ( expr )
identifier ( expr , args )
identifier < typeargs > ( expr )
identifier < typeargs > ( expr , args )
The rewritten form is then processed as a static method invocation, except for the way in which identifier is resolved: 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 process the rewritten method invocation with a method group consisting of all accessible extension methods with the name given by identifier imported by the namespace declaration’s using-namespace-directives. The first method group that yields a non-empty set of candidate methods is the one chosen for the rewritten method invocation. If all attempts yield empty sets of candidate methods, a compile-time error occurs.
The preceeding rules mean that instance methods take precedence over extension methods, and extension methods imported in inner namespace declarations take precedence over extension methods imported in outer namespace declarations. For example:

using N1;
namespace N1
{
    public static class E
    {
        public static void F(this object obj, int i) { }
        public static void F(this object obj, string s) { }
    }
}
class A { }
class B
{
    public void F(int i) { }
}
class C
{
    public void F(object obj) { }
}
class X
{
    static void Test(A a, B b, C c) {
        a.F(1);                // E.F(object, int)
        a.F("hello");        // E.F(object, string)
        b.F(1);                // B.F(int)
        b.F("hello");        // E.F(object, string)
        c.F(1);                // C.F(object)
        c.F("hello");        // C.F(object)
    }
}


In the example, B’s method takes precedence over the first extension method, and C’s method takes precedence over both extension methods.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.