Разрешение метода расширения - PullRequest
7 голосов
/ 15 июля 2009

Я написал метод расширения для String, чтобы получить аргумент char, string.Remove(char). Но когда я использовал это, он вместо этого вызвал метод string.Remove(int) по умолчанию.

Не должно ли присутствие фактического метода иметь более высокий приоритет, чем неявное преобразование?

Ответы [ 2 ]

9 голосов
/ 15 июля 2009

Методы экземпляра имеют приоритет над методами расширения. Ваше наблюдение доказывает то же самое.

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

Перефразировано из C # в глубину,

Когда компилятор видит, что вы пытаясь вызвать метод, который выглядит как метод экземпляра, но не может чтобы найти его, он затем ищет методы расширения (которые видны на основании ваших using директив) . В случай нескольких кандидатов в качестве метод целевого расширения, один с «лучшее преобразование» похоже на перегрузка (например, если IChild и IBase оба имеют похожий метод расширения определены .. IChild.ExtensionMethod является Избранный)

Также может быть скрытый взломщик кода, скажем, у TypeA не было SecretMethod в качестве метода экземпляра в Libv1.0. Итак, вы пишете метод расширения SecretMethod. Если автор вводит метод экземпляра с тем же именем и сигнатурой в v2.0 (без параметра this), и вы перекомпилируете свой исходный код с самой последней версией n-Most Libv2.0, все существующие вызовы метода расширения теперь будут молча перенаправляться на новый метод экземпляра .

2 голосов
/ 15 июля 2009

Это поведение правильно. Причина в том, что введение метода расширения не должно изменять способ выполнения существующего кода. Код должен вести себя точно так же с или без этого «лишнего» метода расширения. В некоторых случаях (например, у вас) это может показаться нелогичным, но это происходит по какой-то причине.

...