2009-07-30 4 views
33

Я вижу много вопросов C#, .net, решенных здесь, используя отражение. Для меня многие из них выглядят как сгибание правил за счет хорошего дизайна (ООП). Многие из решений выглядят немыслимыми и «scripty».Использует отражение дизайн запах?

Является ли использование отражения хорошей практикой в ​​целом? Есть ли вещи, которые могут быть решены только отражением?

редактировать:

Пожалуйста, приведите примеры, когда отражение является единственным хорошим решением.

+2

Я вижу много мнений, но не обсуждаю лучшие практики. –

+1

Нам просто нравится видеть наше имя в печати. Видеть? -> –

+0

Некоторые из вас указали, что отражение имеет место в рамках, тестировании, mocks и т. Д. Как насчет в бизнес-приложениях? – Mank

ответ

0

Нет его интенсивное использование отражения самой чистой структуры точка, которая заработала ему такую ​​большую популярность

использование F # сильно использует отражение

+1

Можем ли мы сказать, что структура имеет разные требования к дизайну, чем приложения, которые ее используют? – Mank

+0

№ MS постоянно дает больше функциональности, основанной на отражении с каждой структурой. например, 4.0 вводят динамические типы. что снова основано на размышлении –

13

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

7

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

+0

Согласовано. Я ищу еще несколько ответов, чтобы увидеть какой-либо консенсус. – Mank

2

Есть некоторые проблемы, которые могут быть решены только с отражением, но я думаю, что его можно и, возможно, следует избегать везде, где это возможно. C# - это статический и безопасный по типу язык, поэтому используйте эти преимущества. Думаю, использование рефлексии часто довольно подвержено ошибкам.

+0

Я согласен, что отражение может быть довольно подверженным ошибкам из-за его динамического характера. – Mank

2

как все вещи ответ «это зависит»

Допустимое использование отражения в рамках, например, рамки плагин может использовать атрибуты для объявления классов плагинов, тестирование и Mocking Каркасы являются еще одним примером.

Но я согласен, что, вообще говоря, в строке бизнес-приложения, большую часть времени он будет «код запах» (не всегда, хотя ....)

+0

Я согласен. Я написал в сообщении Umair, что рамки имеют разные проектные цели, чем бизнес-приложения. Тестирование и издевательские рамки - примеры хорошего использования рефлексии. – Mank

3

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

+1

Пойдите spidey! Идти! Для System.Reflection! –

0

Ну, очевидно, что API-интерфейсы отражения есть, потому что они заполняют необходимость, и есть некоторые проблемы, которые могут быть решены только с использованием рефлексии. В принципе, необходимо учитывать необходимость принятия решений в вашем коде на основе информации о типе, которая доступна только во время выполнения, но не во время компиляции.

+0

Существуют шаблоны проектирования, такие как посетитель, стратегия, позволяющая принимать решение во время разработки на основе информации о типе. – Mank

+0

Я хотел сказать время исполнения вместо времени разработки. – Mank

+1

Говоря, что они «там, потому что они заполняют необходимость», являются очень крутым аргументом и могут быть так же легко применены к практически любой функции любого API или языка программирования. Многие функции существуют только потому, что в то время они казались хорошей идеей. Многие из них были экспериментами. Многие были добавлены просто для заполнения флажка в списке функций. –

3

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

Есть вещи, которые просто невозможны без отражения; Примером может служить любая общая сериализация. Другим может быть любой вид плагинов, который не во время компиляции имеет доступ ко всем классам, с которыми он может работать во время выполнения.

+1

Сериализация - хороший пример. Это большая проблема в большинстве приложений. – Mank

0

Иногда это фактически улучшает повторное использование кода. В качестве конкретного примера я однажды написал программу для импорта csv в базу данных.Используя ORM для создания классов для таблиц, затем, размышляя над ними, я смог создать импортера, где должны были быть отмечены только исключительные ситуации, а добавление столбца, возможно, не требовало ничего, кроме добавления его в таблицу db, и зная, что он существует в файле.

Но, как заявили другие, это, в основном, проблема правильного использования.

6

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

Я бы подумал, что это запах. Может быть, неплохая практика, но что-то, что поднимет бровь.

44

Примеры:

  • Динамическая загрузка типов с помощью конфигурации
  • Использования «Конвенция» регистрации стиля (регистр компонентов с вашим контейнером, которые реализуют интерфейс или имеют определенное соглашение об именах)
  • Проверки/с использованием настраиваемых атрибутов/типов метаданных

Отражение - это инструмент, как «бросок». следует ли использовать везде? Нет! Так это запах кода для использования броска?

+5

Точно то, что я бы написал. – Alex

+0

Точно то, что я хотел бы написать – Benoittr

0

Все отражения позволяют вам наблюдать за типами во время выполнения. Если вы взломали, я полагаю, вы могли бы скомпоновать с ним какое-то устройство Рубе Голдберга, но то же самое можно сказать о многих других методах.

Многие основные функции фреймворка, такие как атрибуты, не будут работать вообще без отражения.

6

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

Например ...

  • принимает строковое представление типа и превращения его в объект.
  • не hardcoding рамки или плагины вместе.
  • динамически используя объекты от различные сборки, не зная , что они заблаговременно.
  • сериализация данных без записи выделенный код для этого.

Используется правильно, это гениальный инструмент для перехода на следующий уровень повторного использования и гибкости. В этом нет ничего плохого.

Единственный раз, когда это запах дизайна, когда он используется для выполнения каких-либо обычных функций. (т. е. вы не захотите использовать Reflection для получения значений DataRow или чего-то еще).

14

Для меня, многие из них похожи на изгиб правила по стоимости хорошего дизайна (ООП). Многие из решений выглядят неподъемными и «scripty».

Честно говоря, «хороший дизайн» имеет мало общего с ООП. Я бы сказал, что гораздо больший дизайнерский запах, который нужно учитывать, - это убеждение, что хороший дизайн точно равен ООП. То, что у нас не может быть хорошего дизайна без ООП, и что мы не можем следовать правилам ООП, не становясь хорошим дизайном. Это почти так же плохо, как одержимость людей «запахами». Программисты должны использовать свои мозги, а не их носы.

Является ли использование отражения хорошей практикой в ​​ вообще? Есть ли вещи, которые могут быть решены путем отражения только ?

Способ, которым я его вижу, отражение в основном является симптомом недостатков языка. В идеале, язык должен позволять вам делать то, что вы хотите, без «сгибания правил» через отражение. Но большинство нет, и C# определенно не делает, поэтому отражение иногда является вашим единственным разумным выбором.

Существует много «правильных» применений отражения. Динамическая загрузка типов/библиотек была бы очевидной. Или проверка атрибутов. Большинство модульных модулей тестирования также зависят от отражения, что прекрасно, потому что они должны быть немного назойливыми, чтобы быть просты в использовании и получить доступ к коду, который мы хотим проверить.

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

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

+0

Согласился, что ООП - не единственный хороший дизайн, но он один из них для многих проблем. В моем вопросе я имел в виду использование рефлексии в проектах ООП, но я думаю, что я был неясно. – Mank

+0

Хороший вопрос о хорошем дизайне. – AraK

+3

@Mank: ООП не является одним из хороших проектов, роль ООП заключается в том, чтобы помочь разработчикам избежать худшего дизайна. Я полностью согласен со всеми точками jalf. У C# есть «языковой запах», а отражение - это быстрое исправление языка C# и недостатков дизайна ООП. Одним из недостатков дизайна ООП является неглубокая модель наследования. – alpav

12

Однажды была программа, которая обрабатывала файлы (как это общее описание)

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

Как и большинство решений. существует ряд других способов достижения той же цели, но отражение сделало это довольно простым.

+1

Спасибо за пример. Как отмечали другие, плагины - хорошее отражение. – Mank

+1

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

1

Нет, Отражение не является запахом дизайна. Его можно было бы назвать «запахом языка/платформы».

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

Для модульности в .NET это большое преимущество, которое модули самоописывают.

Это может быть связано с моим личным развитием в качестве программиста, но я считаю, что рефлексия обучения защищает крайне необходимое внимание к результатам (сборкам). Наряду с TDD, конечно.

2

Отражение позволяет проверять во время выполнения ту же информацию, что и компилятор, во время компиляции. Следовательно, все, что вы можете сделать с отражением, может быть сделано без отражения во время компиляции. Это не означает, что отражение не имеет смысла: вы можете не знать, какой именно вопрос вы хотите задать до выполнения.

Если вы знаете что-то во время компиляции, выразите его в системе типов. Это позволит вам ловить ошибки во время компиляции. Например,

string propVal = myObj.SomeProperty; 

Здесь мы говорим, что мы знаем наверняка, во время компиляции, что myObj имеет свойство SomeProperty, которая имеет тип, который присваиваемые string - и на самом деле, хотя не видно здесь мы также должны указать тип класса или интерфейса myObj.

string propVal = (string)myObj.GetType() 
         .GetProperty("SomeProperty") 
         .GetValue(myObj, null); 

Здесь мы говорим, что myObj может иметь то же свойство - или он не может (и в этом случае мы получим исключение во время выполнения).

Второй, используя отражение, выглядит прикладом-уродливым, но в C# 4.0 он будет выглядеть практически идентичным. Он часто считается слишком медленным, но это зависит от контекста и, вероятно, будет менее справедливым для динамических функций в C# 4.0.

Реальное различие остается, однако: статически типизированная версия помогает нам находить ошибки во время компиляции, вместо того, чтобы откладывать это открытие до времени выполнения.

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

1

Одно приятное использование отражения - это когда вы хотите внедрить надстройку. Вам нужно каким-то образом указать «вот DLL, загрузите его и попробуйте создать экземпляр типа». Вы не знаете тип перед рукой; все, что вы знаете, это то, что там есть какой-то интерфейс, к которому вы можете получить доступ. Единственный способ сделать это - с отражением.

Наше приложение имеет большое количество модулей, которые вы можете запустить внутри него. Вместо жесткого кодирования списка классов, которые мы должны запускать при выборе модуля, у нас есть таблица данных, в которой указано имя DLL модуля и класс для запуска из него. Таким образом, когда нам нужно добавить новый модуль, нам просто нужна новая запись в таблице. Код, запускающий модули, не изменяется.

+0

+1 Это именно то, для чего мы используем Reflection for. Это не запах дизайна *, а также необходимость создания богатой архитектуры addin/plugin. Без отражения это может быть очень сложной задачей. – IAbstract

2

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

Некоторые из вас указали, что отражение имеет место в рамках, тестировании, mocks и т. Д. Как насчет в бизнес-приложениях?

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

0

Это один из самых вонючих запахов. Язык, который «полностью закрыт», не нуждается в отражении.

+1

Можете ли вы пояснить, что вы подразумеваете под «полностью закрытым»? – UserControl

0

Любой может увидеть преимущества использования отражения, и я думаю, что отражение может помочь вам достичь лучшего дизайна и особенно концепций дизайна ООП без написания гораздо большего количества кода.

Например, вы можете создавать слабосвязанные слои, которые зависят от абстракции и использования отражения для управления поведением, характерным для экземпляров во время выполнения.

Наиболее очевидно: обобщенные слои/компоненты пользовательского интерфейса.

Гибкость и производительность ASP.Net MVC и динамических данных являются лишь примером, и вы также можете видеть GridView.

1

Я нахожусь в центре проекта, который использует (для моего первого раза, когда-либо) Отражение. Должен признаться, это выглядит не очень хорошо. Обычно я стараюсь очень минимально комментировать, полагая, что код должен быть максимально комментирующим, но с этим проектом я добавляю частые комментарии; это объясняет, что происходит с следующим разработчиком, которому, возможно, придется поддерживать код, и как «думать вслух» для моей собственной выгоды.

Итог: если он не выглядит явным, добавьте комментарии. Всегда думайте о человеке, который приходит после вас, который может иметь дело с вашим беспорядком. Отражение может выглядеть беспорядочно, поэтому комментарий соответственно.

Смежные вопросы