Использование ключевого слова this в формальных параметрах для статических методов в C #

286

Я встречал несколько примеров кода на C #, таких как:

public static int Foo(this MyClass arg)

Я не смог найти объяснение, что thisозначает ключевое слово в этом случае. Есть идеи?

kpozin
источник
10
В дополнение к принятому ответу для методов расширения C # необходимо ознакомиться с официальной документацией MSDN .
вулкан ворон
4
Методы расширения удобны, но мы должны соблюдать осторожность при их создании / использовании - они могут сломаться! Цитата из Общего руководства в официальной документации MSDN : «В общем, мы рекомендуем вам применять методы расширения экономно и только тогда, когда вам нужно ... ... При использовании метода расширения для расширения типа, исходный код которого вы не можете изменить, вы риск, что изменение в реализации типа приведет к сбою метода расширения. "
Кришна Гупта
Значит ли это, что это возможно? Потому что это то, что я ищу.
facepalm42

Ответы:

274

Это метод расширения . Смотрите здесь для объяснения .

Методы расширения позволяют разработчикам добавлять новые методы к общедоступному контракту существующего типа CLR без необходимости подкласса его или перекомпиляции исходного типа. Методы расширения помогают сочетать гибкость поддержки «утиной типизации», популярной сегодня в динамических языках, с производительностью и проверкой во время компиляции строго типизированных языков.

Методы расширения позволяют использовать множество полезных сценариев и помогают создать действительно мощную инфраструктуру запросов LINQ ....

это означает, что вы можете позвонить

MyClass myClass = new MyClass();
int i = myClass.Foo();

скорее, чем

MyClass myClass = new MyClass();
int i = Foo(myClass);

Это позволяет создавать плавные интерфейсы, как указано ниже.

Прит Сангха
источник
подклассы трудно
Джерри
@ Джерри - что ты имеешь в виду?
Прит Сангха
9
Извините, немного сарказма - многие синтаксисы в наши дни решают проблемы, о которых я даже не подозревал. Читаемость должна быть очень высоким приоритетом.
Джерри
2
Если честно, @ Джерри, это звучит так, будто ты в классическом Blub Paradox . Многие синтаксисы в наши дни решают проблемы, которых у вас нет, потому что вы не знали, что есть лучший способ, или вы не выполняете задачу, для которой этот синтаксис великолепен. Большинство комментариев о « это решение в поисках проблемы » на самом деле является примером « я не знаю, как работает эта функция, поэтому она должна быть бесполезной ».
Мирддин Эмрис
53

Цитируемое сообщение в блоге Скотта Гу хорошо объясняет это.

Для меня ответ на вопрос в следующем утверждении в этом посте:

Обратите внимание, что у статического метода выше есть ключевое слово this перед первым аргументом параметра типа string. Это говорит компилятору, что этот конкретный метод расширения должен быть добавлен к объектам типа «строка». В реализации метода IsValidEmailAddress () я могу затем получить доступ ко всем открытым свойствам / методам / событиям фактического экземпляра строки, к которому вызывается метод, и вернуть истину / ложь в зависимости от того, является ли это действительным письмом или нет.

Джеймс Уайзман
источник
9
Это должен быть принятый ответ. Это единственный ответ, который фактически объясняет, какова цель thisключевого слова в сигнатуре метода. Другие ответы бесполезно говорят «это метод расширения». Я никогда полностью не понимал, как методы расширения «присоединяются» к типам, которые они расширяют, до прочтения этого ответа. Спасибо!
Льюс Терин
13

В дополнение к объяснению Прита Сангхи:
Intellisense отображает методы расширения с синей стрелкой (например, перед «Aggregate <>»):

введите описание изображения здесь

Ты нуждаешься в

using the.namespace.of.the.static.class.with.the.extension.methods;

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

Оливье Жако-Дескомб
источник
4

Я только что узнал об этом на днях: ключевое слово this определяет, что метод является расширением класса, который его обрабатывает. Так что для вашего примера MyClass будет иметь новый метод расширения с именем Foo (который не принимает никаких параметров и возвращает int; его можно использовать как с любым другим открытым методом).

jpoh
источник
1

«this» расширяет следующий класс в списке параметров

Таким образом, в сигнатуре метода ниже «this» расширяет «String». Строка передается функции как обычный аргумент метода. открытая статическая строка [] SplitCsvLine (эта строка String)

В приведенном выше примере класс «this» расширяет встроенный класс «String».

dcarl661
источник