Метод расширения - действительно полезная функция, которую вы можете добавить в любой класс множество функций. Но мне интересно, есть ли недостатки, которые могут вызвать проблемы для меня. Любые комментарии или предложения?Недостатки методов расширения?
ответ
- таким образом, что методы расширения импортируются (то есть целое пространство имен в то время) не зернистый. Вы не можете импортировать одно расширение из пространства имен, не получая все остальное.
- Это не сразу видно из исходного кода, где определяется метод. Это также преимущество - это означает, что вы можете сделать свой код похожим на остальные методы этого типа, даже если вы не можете поместить его в одно и то же место по любой причине. Другими словами, код проще понять на высоком уровне, но более сложным с точки зрения точно того, что выполняется. Я бы сказал, что это верно и для LINQ в целом.
- У вас могут быть только методы расширения, а не свойства, индексы, операторы, конструкторы и т. Д.
- Если вы расширяете сторонний класс и в более поздней версии вводите новый метод с той же подписью, Легко понять, что значение вашего кода вызова изменилось. Если новый метод очень похож на на ваше расширение, но с не совсем разными граничными условиями (или что-то еще), то это может привести к некоторым очень сложным ошибкам. Хотя это вряд ли произойдет.
Что касается недостатков, я бы увидел их немного как макросы - вы можете в конечном итоге получить код, который сложнее поддерживать, потому что другие могут быть не знакомы с добавленными вами расширениями.
Методы расширения - это весело, но с ними возникают потенциальные проблемы. Например, что, если вы пишете метод расширения, а другая библиотека создает метод расширения с той же сигнатурой? Вы столкнетесь с трудностями при использовании обоих пространств имен.
Кроме того, можно утверждать, что они менее узнаваемы. Я думаю, это зависит от этого. В некоторых случаях ваш код должен быть завершен в классе, в других случаях прекрасно добавлять эту функциональность в качестве метода расширения.
Обычно я использую методы расширения в качестве оболочек для своих классов или классов BCL и помещаю их в другое пространство имен. например Utils и Utils.Extensions. Таким образом, расширения не должны использоваться.
Пара вещей:
- Это не всегда ясно, где метод расширения происходит от, если вы не в VS.NET
- Методы расширения не могут быть решены с помощью отражения или C# 4.0-х динамический поиск
Вы можете найти методы расширения с помощью отражения. Найдите атрибут «ExtensionAttribute». Взгляните на http://stackoverflow.com/questions/299515/c-reflection-to-identify-extension-methods – Patrik 2008-11-23 12:58:06
@Patrik - но вы не можете сделать это однозначно, так как вы не знаете, какие «приемы», следует считать. Иногда это имеет значение. – 2008-11-23 15:46:49
@Patrik: То, что я имел в виду «разрешение», было: в то время как вы можете вызвать myType.extendedMethod(), вы не можете сделать это с помощью обычного кода отражения, то есть typeof (MyType) .GetMethod («extendedMethod»). Invoke (...) или динамический поиск, то есть динамический myType = new MyType(); myType.extendedMethod(); – 2008-11-26 15:02:35
Нулевая проверки со статическими методами отличается. Не обязательно лучше или хуже - но разные, и разработчик должен это понимать. Возможность вызова метода по нулевому значению может быть неожиданным и может (время от времени) быть очень полезным.
Нет полиморфизм (хотя перегрузка поддерживается)
Вы можете попасть впросак с двусмысленностью, если два метода расширения конфликта для типа источника (и ни один не квалифицируется как «лучше»). Затем компилятор отказывается использовать либо ... что означает, что добавление метода расширения в сборке A может нарушить * несвязанный код в сборке B. Я видел это пару раз ...
Вы не можете использовать с C# 2.0, поэтому, если вы пишете библиотеку для C# 2.0, это не помогает
Нужно [ExtensionAttribute] - поэтому, если вы пишете библиотеку для .NET 2.0, вы попадаете в рассол: если вы объявить собственный [ExtensionAttribute], может конфликтовать с абонентом в .NET 3.5
Do не поймите меня неправильно, хотя - я большой поклонник!
Возможно, вы, наверное, догадались, что я сейчас пишу библиотеку, которая должна работать на C# 2.0 и .NET 2.0, и где (досадно) методы расширения были бы действительно полезны!
* = только для компилятора; код, который уже скомпилирован, будет
Его трудно представить, чтобы добавить метод, не зная о существующем коде. Например, вы использовали сторонний класс для выполнения чего-то, что вам нужно расширить функциональность этого класса, учитывая, что вы не являетесь оригинальным разработчиком, и у вас нет идей, как вещи структурированы в класс? Это почти бессмысленно делать так, как будто бессмысленно двигаться, когда вы не можете видеть. В случае LINQ, где он реализован дизайнерами/кодами Microsoft, это имеет большой смысл, поскольку они обладают знаниями о том, как сказать внутреннюю реализацию последовательности, и теперь они хотят расширить свою функциональность, добавив метод Count для подсчета всех элементы в последовательности. Сказав это, я хочу, чтобы кто-то поспорил меня неправильно, представив реалистичный пример, где необходим метод расширения.
@ дублированные подписи комментарий: Его неотъемлемый риск на многих других языках тоже, и люди управляют ОК. Хотя это все еще может быть недостатком, это маловероятно, в большинстве случаев, ИМО. – Chris 2008-11-23 06:25:56