Почему «static» и «this» необходимы для методов расширения и как распределяется их память? - PullRequest
8 голосов
/ 20 апреля 2011

Несколько вопросов о методах расширения:

  1. Почему методы расширения статичны?

  2. Почему они должны быть объявлены в статическом классе?

  3. Что указывает это ключевое слово в списке параметров метода расширения? Как это статический класс, как работает ключевое слово "this" в этом контексте?

  4. Как происходит распределение памяти для методов такого типа?

Ответы [ 5 ]

8 голосов
/ 20 апреля 2011

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

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

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

3 голосов
/ 20 апреля 2011

Почему методы расширения статичны?

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

Почему они должны быть объявлены в статическом классе?

Потому что мы не должны создавать экземпляры класса. Это дизайнерское решение. Зачем усложнять такие вещи, как наличие экземпляров некоторого класса, к которому прикреплены методы расширения, которые могут даже не использоваться?

Что указывает это ключевое слово в списке параметров метода расширения? Как это статический класс, как работает ключевое слово "this" в этом контексте?

Это статический метод. this не имеет смысла в этом контексте. this в подписи является просто способом обозначения того, что метод расширения объявляется.

Как происходит распределение памяти для методов такого типа?

Запутался об этом. Все они являются статическими методами в статическом классе. Они «выделяются», как и любой другой (статический) метод, для этого типа есть только одна копия кода.

1 голос
/ 20 апреля 2011

Ответ на 1,2 и 4 почти одинаков.Методы расширения - это просто статические методы с некоторым специальным синтаксическим сахаром.Это:

public static void DoIt(this string str) {
    // ..
}

"test".DoIt();

Фактически тот же IL, что и:

public static void DoIt(string str) {
    // ..
}

DoIt("test");

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

Ответ на вопрос № 3 - это только синтаксис, который выбрали дизайнеры языка.C # разработчики привыкли this ссылаться на объект экземпляра.Они могли бы назвать его blah, но это не было бы так же очевидно, как и объект экземпляра.

Использование ключевого слова this в методе расширения также говорит компилятору C # пометить его как ExtensionAttribute .Этот атрибут используется потребителями сборки для поиска методов расширения.

1 голос
/ 20 апреля 2011
  1. Потому что нет экземпляра для вызова их.

  2. Я думаю, это ограничивает число возможных ошибок, если оно было объявлено в нестатическом классе.

  3. Это говорит о его методе расширения. Компилятор видит это и позволяет использовать его для типа, объявленного как this, вместо статического метода.

  4. Вызов метода расширения является только синтаксическим сахаром. Этот вызов преобразуется в обычный вызов статического метода в IL.

0 голосов
/ 20 апреля 2011

Вот как они определены - это ключевое слово предшествует первому параметру, который является экземпляром объекта, для которого вы вызываете метод. Почему ToString () называется ToString ()? Почему статика используется для статики? Почему трава зеленая? Я полагаю, что полномочия, которые будут решены поставить this перед первым параметром, вместо того, чтобы придумать новое ключевое слово "extension", чтобы поставить перед именем метода.

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

...