Приоритет метода расширения C # - PullRequest
12 голосов
/ 23 сентября 2011

Я немного озадачен тем, как работают методы расширения.

Если я правильно читаю http://msdn.microsoft.com/en-us/library/bb383977.aspx и это Если метод расширения имеет ту же сигнатуру, что и метод в запечатанном классе, каков приоритет вызова? .

Затем следующее должно выписать «Экземпляр», но вместо этого оно пишет «Метод расширения».

interface IFoo
{
}

class Foo : IFoo
{
    public void Say()
    {
        Console.WriteLine("Instance");
    }
}

static class FooExts
{
    public static void Say(this IFoo foo)
    {
        Console.WriteLine("Extension method");
    }
}

class Program
{
    static void Main(string[] args)
    {
        IFoo foo = new Foo();
        foo.Say();
    }
}

Ценю любую помощь в разъяснении поведения.

Ответы [ 2 ]

14 голосов
/ 23 сентября 2011

Большая разница в том, что вы определили метод расширения для интерфейса IFoo, а ваша переменная foo имеет тип IFoo.

Если ваш код должен был выглядеть так:

Foo foo = new Foo();
foo.Say()

Будет выполнен метод Foo.Say (), а не метод расширения.

Хотел бы я дать вам подробное объяснение, почему это так, но я могу охватить только основной механизм. Поскольку ваша переменная имела тип IFoo, а не Foo, когда компилятор попытался определить, какие методы были доступны, он смотрел мимо любых неинтерфейсных методов класса Foo (как и должно быть). Однако был доступен метод расширения Say(), поэтому он вызвал это.

4 голосов
/ 23 сентября 2011

В вашем Main, foo объявлено как IFoo.Когда компилятор ищет метод Say, он находит только метод расширения.Это связано с тем, что метод экземпляра объявлен в Foo, а не в IFoo.Компилятор не знает, что переменная foo содержит экземпляр Foo;он просто смотрит на тип, для которого объявлена ​​переменная.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...