Методы расширения на самом деле не являются частью объекта, для которого вы вызываете метод. Методы расширения находятся в дополнительной области поиска, которую ищет компилятор после поиска метода в области самого объекта.
Таким образом, для вызова метода, подобного obj.MyExtension()
, компилятор будет искать «MyExtension» в членах типа переменной obj. Он не найдет совпадений, потому что «MyExtension» не определено в типе объекта. Затем компилятор ищет методы расширения с именем «MyExtension», которые доступны в текущей области (из-за использования предложений), у которых есть параметр this
, тип которого соответствует типу переменной экземпляра obj. Если совпадение найдено, то компилятор генерирует код, чтобы статический метод вызывал этот другой метод, передавая obj в параметре this
.
Я считаю, что область действия методов расширения - это поиск "последнего шанса" - если компилятор не может найти "MyExtension" в доступных расширениях, следующим шагом будет сбой с ошибкой компиляции.
Хитрость в методах расширения заключается в том, что они доступны только в том случае, если вы добавили соответствующее условие using в текущий исходный файл и добавили ссылку на соответствующую сборку, которая реализует расширения, чтобы перенести их в Объем.
Intellisense не поможет вам разрешить эти имена, добавив соответствующее условие использования для вас. Как пользователь, вы привыкаете к вызову определенного метода для определенного типа объекта и мысленно связываете этот метод как часть этого типа. Когда вы конкретизируете новый исходный файл, очень часто пишутся вызовы этого метода, как обычно, и вы получаете «не найденные» ошибки компилятора, потому что вы забыли сослаться на пространство имен / сборку, содержащее определения метода расширения, на ваш исходный файл.