Являются ли методы расширения объектно-ориентированной особенностью C#?

Следуют ли методы расширения объектно-ориентированной парадигме в C#?

Полезно ли использовать методы расширения?

В жизненном цикле разработки программного обеспечения, как мы должны рассматривать этот вопрос на этапе проектирования?

6 ответов

Решение

Методы расширения не являются объектно-ориентированной особенностью языка. (по сравнению с: классами, наследованием, полиморфизмом и т. д.).

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

Эрик Липперт написал об этом в блоге, и я подозреваю, что не могу сделать намного лучше, чем процитировать его:

Так что да, часто звучащая критика о том, что "методы расширения не являются объектно-ориентированными", совершенно верна, но также не имеет значения. Методы расширения, безусловно, не являются объектно-ориентированными. Они помещают код, который манипулирует данными, далеко от кода, который объявляет данные, они не могут нарушать инкапсуляцию и общаться с закрытым состоянием объектов, для которых они выглядят как методы, они плохо работают с наследованием и так далее. Это процедурное программирование в удобном объектно-ориентированном платье.

Они также невероятно удобны и делают возможным использование LINQ, поэтому мы добавили их. Тот факт, что они не соответствуют некоторому философскому идеалу того, что делает объектно-ориентированный язык, на самом деле не был важным фактором в этом решении.

Однако я бы добавил, что они полезны не только для LINQ - по той же причине, что и в LINQ. Очень хорошо иметь возможность выражать алгоритмы, которые работают на произвольных реализациях определенного интерфейса (таких как IEnumerable<T> в LINQ to Obhects). Такие алгоритмы обычно не имеют никакого контекста, кроме интерфейсов, над которыми вы работаете, поэтому они часто являются статичными.

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

// Traditional
CollectionUtils.Sort(collection);

// Extension methods
collection.Sort();

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

Есть две части к этому.

  1. Это ОО, когда мы используем его Нет; это заставляет вас чувствовать, что вы вызываете метод определенного типа

  2. Это ОО, основанное на том, как оно скомпилировано / собрано

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

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

Методы расширения - это просто статические методы, которые работают с определенным классом или иерархией классов. Python является OO, но имеет модули, а Ruby имеет миксины. Я вижу это больше как языковую особенность. Я уверен, что все еще ОО дружелюбный

Методы расширения - это всего лишь языковая функция. Они работают с экземплярами объектов и являются очень хорошим инструментом.

Рассматривайте их как другой способ расширения функциональности класса. Вы можете добавить новую функциональность в класс:

  • Добавляя частичное объявление класса. Затем класс мгновенно получает кучу новых методов и свойств.

  • Включая пространство имен с вашим классом держателей методов расширения. Затем класс снова получает кучу новых методов.

Скорее организационная / языковая особенность. Никоим образом не нарушает объектно-ориентированную концепцию. Точно так же, как разделение заголовочных / исходных файлов в C/C++ не имеет ничего общего с объектной ориентацией, это просто функция языка / инфраструктуры.

Другие вопросы по тегам