Являются ли методы расширения объектно-ориентированной особенностью C#?
Следуют ли методы расширения объектно-ориентированной парадигме в C#?
Полезно ли использовать методы расширения?
В жизненном цикле разработки программного обеспечения, как мы должны рассматривать этот вопрос на этапе проектирования?
6 ответов
Методы расширения не являются объектно-ориентированной особенностью языка. (по сравнению с: классами, наследованием, полиморфизмом и т. д.).
Как и любая языковая функция, ее следует использовать там, где это уместно и для чего она предназначена. Уже есть десятки вопросов о том, когда и как использовать методы расширения.
Эрик Липперт написал об этом в блоге, и я подозреваю, что не могу сделать намного лучше, чем процитировать его:
Так что да, часто звучащая критика о том, что "методы расширения не являются объектно-ориентированными", совершенно верна, но также не имеет значения. Методы расширения, безусловно, не являются объектно-ориентированными. Они помещают код, который манипулирует данными, далеко от кода, который объявляет данные, они не могут нарушать инкапсуляцию и общаться с закрытым состоянием объектов, для которых они выглядят как методы, они плохо работают с наследованием и так далее. Это процедурное программирование в удобном объектно-ориентированном платье.
Они также невероятно удобны и делают возможным использование LINQ, поэтому мы добавили их. Тот факт, что они не соответствуют некоторому философскому идеалу того, что делает объектно-ориентированный язык, на самом деле не был важным фактором в этом решении.
Однако я бы добавил, что они полезны не только для LINQ - по той же причине, что и в LINQ. Очень хорошо иметь возможность выражать алгоритмы, которые работают на произвольных реализациях определенного интерфейса (таких как IEnumerable<T>
в LINQ to Obhects). Такие алгоритмы обычно не имеют никакого контекста, кроме интерфейсов, над которыми вы работаете, поэтому они часто являются статичными.
Если вы согласитесь, что у вас есть какой-то статический служебный метод, какой синтаксис вы бы предпочли использовать?
// Traditional
CollectionUtils.Sort(collection);
// Extension methods
collection.Sort();
Последнее просто более читабельно, на мой взгляд. Это сжато выражает то, что вы хотите сделать. Неясно, как вы хотите это сделать, но это не так важно в большинстве случаев, и, конечно, более важно, когда вы отлаживаете эту конкретную строку.
Есть две части к этому.
Это ОО, когда мы используем его Нет; это заставляет вас чувствовать, что вы вызываете метод определенного типа
Это ОО, основанное на том, как оно скомпилировано / собрано
Да; Скомпилированный код имеет статический метод, использующий объект, для которого был вызван метод расширения.
Это зависит. Методы расширения - это всего лишь инструмент. Они могут быть очень полезны при правильном использовании. Но если вы используете их слишком много, это может затенить ваш код.
Методы расширения - это просто статические методы, которые работают с определенным классом или иерархией классов. Python является OO, но имеет модули, а Ruby имеет миксины. Я вижу это больше как языковую особенность. Я уверен, что все еще ОО дружелюбный
Методы расширения - это всего лишь языковая функция. Они работают с экземплярами объектов и являются очень хорошим инструментом.
Рассматривайте их как другой способ расширения функциональности класса. Вы можете добавить новую функциональность в класс:
Добавляя частичное объявление класса. Затем класс мгновенно получает кучу новых методов и свойств.
Включая пространство имен с вашим классом держателей методов расширения. Затем класс снова получает кучу новых методов.
Скорее организационная / языковая особенность. Никоим образом не нарушает объектно-ориентированную концепцию. Точно так же, как разделение заголовочных / исходных файлов в C/C++ не имеет ничего общего с объектной ориентацией, это просто функция языка / инфраструктуры.