Есть ли из этих двух способов цепочки методов расширения какая-либо причина использовать один поверх другого? - PullRequest
1 голос
/ 10 февраля 2012

Допустим, у меня есть перегруженный метод расширения со следующими двумя сигнатурами:

public static void MyExtensionMethod(this Foo foo);
public static void MyExtensionMethod(this Foo foo, Bar bar);

Я бы хотел связать один метод с другим. Я могу сделать это одним из двух способов:

Техника сцепления # 1

public static void MyExtensionMethod(this Foo foo)
{
    // Call overload using extension method syntax.
    foo.MyExtensionMethod(new Bar());
}

public static void MyExtensionMethod(this Foo foo, Bar bar)
{
    // Do stuff...
}

Техника сцепления # 2

public static void MyExtensionMethod(this Foo foo)
{
    // Call overload as a regular method.
    MyExtensionMethod(foo, new Bar());
}

public static void MyExtensionMethod(this Foo foo, Bar bar)
{
    // Do stuff...
}

Это мой вопрос: есть ли разница между вызовом перегруженного метода как метода расширения и обычного метода? Если так, то в чем разница? Один предпочтительнее другого?

Ответы [ 4 ]

6 голосов
/ 10 февраля 2012

Предполагая, что компилятор может разрешить все, они должны выводиться как эквивалент MSIL.Методы расширения - это просто хитрости компилятора;они являются статическими методами в реальности.

В своем ответе отмечает, что если у вас есть экземпляр метода с тем же именем, вы можете столкнуться с проблемами. Я согласен ... и, как следствие, настоятельно призываю вас никогда называть метод расширения так же, как любой метод экземпляра.

3 голосов
/ 10 февраля 2012

Этот вопрос эквивалентен вопросу: «Есть ли разница между вызовом метода расширения как расширения и статического метода?». Ответ - нет. Компилятор переводит оба вызова в один и тот же код.

3 голосов
/ 10 февраля 2012

Я считаю вашу технику 2 более естественной для чтения.

Первый из них немного раздражает - мне нужно понять, что он вызывает второй метод расширения.

Итак, только для удобства чтения я бы выбрал технику 2.

С точки зрения того, как все вызывается, методы расширения являются просто синтаксическим сахаром для вызовов статических методов. Оба примера равносильны одному и тому же.


Существует одно исключение, как отмечено в ответе @Servy - если у вас есть метод экземпляра с точно такими же именем и параметрами (кроме первого this параметра), у вас могут возникнуть проблемы. Хотя это вряд ли произойдет в вашей собственной кодовой базе, это может произойти - просто следствие использования методов расширения.

Это плохая практика - не называйте методы экземпляров так же, как методы расширения.

1 голос
/ 10 февраля 2012

Второй на самом деле более стабильный. Первый изменится, если я сделаю что-то вроде:

public class Foo
{
    public void MyExtensionMethod(Bar bar)
    {
        Console.WriteLine("instance method");
    }
}

Если я добавлю это, то в первом случае вызовет метод экземпляра, а во втором - метод расширения.

...