2013-10-02 6 views
6

В чем разница между методом расширения и статическим методом?В чем разница между методом расширения и статическим методом?

У меня есть два класса, как это:

public static class AClass { 
    public static int AMethod(string ....) 
    { 
    } 
} 

и

public static class BClass { 
    public static int BMethod(this string ....) 
    { 
    } 
} 

Я могу использовать их как

AClass.AMethod('...'); 

или

'...'.BMethod(); 

Что предлагается?

ответ

27

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

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

int result = stringValue.BMethod(); 

Вместо:

int result = BClass.BMethod(stringValue); 

Это работает исключительно как компиляционный «трюк» - компилятор видит первую форму, и если BClass можно использовать (он имеет надлежащее using и находится в ссылочной сборке), то он превратит его в IL-код второго метода для вы. Это просто удобство.

Что предлагается?

Это действительно зависит. Если вы будете управлять типом, я бы рекомендовал поместить методы в этот тип. Это, как правило, более удобно.

Если вы не контролируете тип или пытаетесь «расширить» общий тип (например, IEnumerable<T>), то методы расширения могут быть разумным.

Однако, если тип является очень распространенным типом, я обычно избегаю методов расширения, поскольку они становятся «шумом» в intellisense, что, в свою очередь, может вызвать дополнительную путаницу. Например, я лично не рекомендовал бы добавлять методы расширения на System.Object или System.String и т. Д.

+2

Очень хорошо сказано (как всегда), Рид. +1 – Brian

1

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

Урок есть некоторые ограничения: Методы расширения должны быть реализованы как статические методы и статические классы (точнее, внутри не-вложенного, неэквивалентного статического класса). Вы можете использовать методы расширения для расширения класса или интерфейса, но не для их переопределения. Метод расширения с тем же именем и сигнатурой как интерфейс или метод класса никогда не будет вызван. Во время компиляции методы расширения всегда имеют более низкий приоритет, чем методы экземпляров, определенные в самом типе. Методы расширения не могут получить доступ к закрытым переменным в том типе, который они распространяют. Вы можете рассмотреть методы расширения как «законный» способ добавления более статических методов к существующим классам, фактически не наследуя их. Но самое смешное, что в отличие от обычных статических методов класса вы не можете вызывать методы расширения на уровне класса (вы получите ошибку времени компиляции, если вы попробуете это), но вместо этого вы должны вызывать их на экземпляре класса (как если бы они были обычными методами экземпляра этого класса, которых они не являются !!!).

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

Смежные вопросы