Intereting Posts
DataGridView автоматически заполняет колонку comboBox, не сохраняя значения при первоначальном закрытии ячейки Linq выберите новый объект отправка сообщения в сеансе групповой беседы через vc # Есть ли увеличение производительности при удалении ненужных пространств имен (с использованием) директив? Как читать изображение с помощью IDataReader Почему var оценивает System.Object в «foreach (var row in table.Rows)»? Выполните анализ из процесса, который обновляет одну консольную линию Параметр недействителен при создании изображения из байта в c # Предотвратить выделение текстового поля только для чтения в Silverlight Передача параметра фоновой работе DropDownListFor с настраиваемым атрибутом с именем атрибута – in? Как создать IDirect3DSurface из массива IBuffer или байтов в UWP Существует ли сетевая библиотека низкого уровня для обнюхивания и изменения сетевого трафика? Сортировка ObservableCollection по строкам Есть ли что-то, что предотвращает Response.Redirect для работы внутри блока try-catch?

Почему методы C # расширения должны быть определены в статических classах?

Я понимаю, что методы расширения C # должны быть статическими. Я не понимаю, почему эти расширения не могут быть определены в нестационарных classах или общих?

Обновление: меня интересует причина этого дизайнерского решения.

Это скорее наблюдение, чем ответ, но …

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

Когда вы определяете метод расширения, вы явно определяете «this» в качестве первого аргумента.

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

Взгляните на эту часть спецификации .NET C #:

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

И этот fragment из ответа Джона Скита :

Мне непонятно, почему все эти ограничения необходимы – кроме потенциально для простоты компилятора (и языка). Я понимаю, почему имеет смысл ограничивать его не-генерическими типами, но я не могу сразу понять, почему они должны быть не вложенными и статичными. Я подозреваю, что правила поиска значительно упрощаются, если вам не нужно беспокоиться о типах, содержащихся в текущем типе и т. Д., Но я осмелюсь сказать, что это было бы возможно.

Потому что спецификация говорит так … Теперь, вероятно, есть веские причины, по которым они написали спецификацию таким образом.

Причина, по которой они не могут быть объявлены в родовых classах, совершенно очевидна: с учетом того, как вызываются методы расширения, где бы вы указали аргумент типа для classа?

Причина, почему это должен быть статический class, менее очевидна, но я думаю, что это имеет смысл. Основным прецедентом для статических classов является объединение вспомогательных методов вместе (например, Path , Directory , ProtectedData …), а методы расширения – это в основном вспомогательные методы. Разумеется, было бы невозможно создать экземпляр Enumerable или Queryable , например.