В сегодняшней статье рассмотрим методы расширения, что это такое и зачем. Мы уже сталкивались с ними, когда рассматривали LINQ (по сути, весь LINQ написан как набор методов расширения), но теперь научимся писать их сами.
Методы расширения
Итак, предположим, мы пишем какой-то код, и в какой-то момент получаем ситуацию, что мы имеем Id экземпляра. Нам надо из этого экземпляра получить тип, а затем у этого типа записать определённое значение в параметр. Мы вынесли всё это в отдельный метод:
Ну, метод и метод, нормальный метод (если не смотреть на LookupParameter). Можно переиспользовать. В коде он будет вызываться так:
SetTypeParameter(id, "param", "Value");
Однако, мы можем вынести этот метод в отдельный класс, и чуть его модифицировать:
Обратите внимание, теперь первым аргументом мы передаём this ElementId.
Теперь мы можем вызывать этот метод по другому:
id.SetTypeParameter("Name", "Value");
И даже IntelliSense подсказывает:
Но главное преимущество тут в том, что мы можем вынести такой метод в отдельный проект, или даже отдельную сборку, и переиспользовать "в один клик" в любых других проектах. Главное, потом не запутаться с версиями своих расширений и не забыть добавить их в установочный файл.
Готовые библиотеки методов расширений
На самом деле, на этом по статье у меня всё. Я бы мог показать это на нескольких примерах, но принципиально ничего бы не изменилось — просто выносим всё в отдельный статический класс и пишем статический метод с передачей ему аргумента с модификатором this. Однако, я хочу рассказать о библиотеке RevitExtensions от Романа Карповича Nice3Point. Я несколько раз писал о его шаблонах, но тут отдельно остановлюсь на методах расширения, которые входят в шаблон:
Здесь есть расширения на многие классы, подробнее обо всех можно почитать прямо в описании репозитория. Я же акцентирую внимание на тех, которые сам чаще всего использую:
1. Метод ToElement<T>(document) в ElementIdExtensions. Превращает Id в элемент, при необходимости приводит к типу Т, и всё это в одну строку
2. document.EnumerateInstances<T>() в CollectorExtensions. Заменяет FilteredElementCollector в меньшее число строк. При необходимости приводит к типу Т (если его передать). Так же можно передать фильтры или BuiltInCategory, или Id вида, если в том есть необходимость — у метода есть соответствующие перегрузки.
3. Метод Round(int n) у SystemExtensions округлит double до n знаков без конструкции Math.Round(...).
Заключение
Статья получилась короткая, но и тема на самом деле не сложная: методы расширения ведь по сути те же самые обычные методы, это лишь один из способов их оформления.
На всякий случай, приводимый в скринах на статье код я добавил себе на GitHub в репозиторий блога. Не забывайте подписываться на мой телеграм-канал и до новых встреч на страницах блога!