Подтвердить что ты не робот

Когда вы используете отражение? Модели/анти-паттерны

Я понимаю API отражения (в С#), но я не уверен, в какой ситуации я его буду использовать. Каковы некоторые шаблоны - анти-шаблоны для использования отражения?

4b9b3361

Ответ 1

Единственное место, где я использовал материал Reflection в С#, было в шаблонах factory, где я создаю объекты (в моем случае, сетевые прослушиватели) на основе информации файла конфигурации. Конфигурационный файл предоставил расположение сборок, имя типов внутри них и любые дополнительные аргументы. factory выбрал этот материал и создал слушателей на основе этого.

Ответ 2

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

Ответ 3

Я не знаю, является ли это шаблоном, но я использую отражение для генерации SQL из определений класса DAO.

Ответ 4

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

Ответ 5

Я использовал отражение во многих местах. К основным широким категориям относятся:

  • Автогенерируемые графические интерфейсы (т.е. редактор свойств). Вы можете перебрать свойства объекта и использовать реестр элементов элементов пользовательского интерфейса для создания формы. Я использую атрибуты свойств для указания создания пользовательского интерфейса.
  • Сериализация. Я написал схемы сериализации для использования в сериализации и десериализации объектов.
  • Веб-службы. Подобно сериализации, я использовал отражение для создания и использования SOAP-сообщений, а также для создания WSDL.
  • Языки домена. Интерпретированные языки сценариев обычно связываются с объектами и методами, использующими отражение.
  • Инструменты отладки. Такие инструменты могут использовать отражение для изучения состояния объекта. Удобен для создания журнальных сообщений в условиях сбоя.

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

Использование отражения является мощным, но оно не сделает вас более популярными на вечеринках. Используйте его только там, где муфта намеренно слаба. Настолько слабый, что вы ожидаете, что он сломается во время работы. Отличным примером является привязка данных в WPF.

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

Ответ 6

Я нахожу отражение (в сочетании с загрузкой классов во время выполнения) незаменимым для реализации плагинов:

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

Ответ 7

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

Ответ 8

Я использую его в двоичном сериализаторе (protobuf-net). Я использую отражение только для создания модели - когда она используется (т.е. Во время сериализации [de]), она использует делегаты и т.д. Для максимальной производительности.

Я также использовал его (вместе с ComponentModel и Reflection.Emit) в HyperDescriptor, чтобы построить ускоренный доступ к свойствам (~ 100x скорость регулярное отражение).

И по необходимости вам нужно использовать отражение, если вы создаете свой собственный Expression s.

Ответ 9

Я использую отражения в моих модульных тестах, особенно когда вещи, которые я проверяю, являются анонимными типами. Я также использовал его как способ легко клонировать/копировать объекты модели. Вместо того, чтобы писать код для этого для каждого объекта модели, я могу легко создать объект определенного типа с использованием отражения, опросить общедоступные свойства входящего объекта и вызвать средства определения объектов клонированных объектов. Я также использую его с создаваемыми конструктором классами, которые реализуют одни и те же сигнатуры методов, но не имеют связанного с ними интерфейса. В этих случаях я могу опросить объект, чтобы узнать, есть ли у него требуемый метод и вызвать его, если это произойдет. Объекты LINQ2SQL похожи на это, поэтому в моем методе OnSubmit для подделки данных я использую отражение, чтобы получить метод OnValidate и вызывать его для модульного тестирования.

Ответ 10

+1 при использовании шаблона factory - очень мощный.

Помимо шаблона factory, каждый раз, когда я его использовал, я, вероятно, не должен был...

Я использовал его для динамической загрузки классов, которые реализуют определенные интерфейсы (мои элементы меню из сборок) при запуске, и я действительно сожалею об этом использовании. Хотелось бы, чтобы я загрузился из файла конфигурации (и позже добавил форму, которая показывала доступные интерфейсы для загрузки). Это круто, но ужасно медленно...

Анти-шаблон должен использовать его свойства доступа, которые разработчики классов помечены как частные, не зная, почему они пометили их как частные. Я сделал это с помощью элемента управления DataGridView WinForms, чтобы отключить логическую переменную, чтобы у меня был столбец "компаньона", когда его приложение было перемещено. Еще раз, это очень здорово, но этот код не удастся, если новый релиз изменит это частное свойство (он очень хорошо может исчезнуть в версии 3.0 или 3.5...).

Ответ 11

Я пошел на 2 года развития, не понимая цели размышлений. Он имеет очень нишу, но чрезвычайно эффективен, когда он является правильным инструментом для работы.

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

Ответ 12

Я использую его в случае, аналогичном тому, что упоминается Харпером Шелби, в котором файл конфигурации указывает во время выполнения, для которого экземпляр объекта создается. В моем конкретном случае нет ничего более сложного, чем factory - только набор классов, реализующих общий интерфейс, и простую функцию, которая читает файл конфигурации и создает соответствующий объект, возвращая интерфейс.

Ответ 13

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

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

Вместо этого я сохраняю строку отражения в БД, которая сообщает классу "создать один из этих...". Поскольку я (программист) всегда гарантирует, что класс получен из одного базового класса, идея работает. Он чист и эффективен.

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

(введите голос мудрого, старого мудреца)
Отражение приходит с невероятной силой... используйте силу с мудростью.

Ответ 14

Я чаще всего использую его, когда мне нужно сломать инкапсуляцию какого-то другого (как правило, рамки). То есть мне нужно изменить какое-то частное поле или вызвать частный метод или создать экземпляр некоторого внутреннего класса в библиотеке, в которой я не могу изменить. Хорошим примером является код в мой ответ на этот вопрос. В этом случае поведение каркасного метода ServiceBase.Run было неприемлемым, поэтому я использовал отражение, чтобы сделать то же самое, что и в более приемлемый способ.

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

Ответ 15

Отражение позволяет решать проблемы, которые в противном случае потребовали бы дублирования кода. Если вы обнаружите, что копируете и вставляете код, и не можете увидеть, как может помочь шаблон OO, возможно, если вы можете их назвать, тогда может помочь команда "r".

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

Скажем, у вас много объектов GUI, таких как Forms или "table". Он привязывается к бизнес-объекту, например, к клиенту:

public class Customer
{
   public string FirstName;
   public string LastName;

}

Ваши пользователи не хотят видеть заголовки столбцов "FirstName" или "LastName". Они хотят "христианское имя" и фамилию. Вы не хотите кодировать литеральные строки во всех ваших объектах графического интерфейса, если они передумают, чтобы "Имя" и "Фамилия отца" (я знаю, пример дерьма).

Если вы определяете свой класс с помощью атрибутов:

public class Customer
{
   [Description("Christian Name")]
   public string FirstName;

   [Description("Surname")]
   public string LastName;

}

Вы можете использовать отражение, чтобы вывести имена столбцов. Если вам нужно изменить способ все, объекты GUI описывают объект клиента, вы теперь делаете это в одном месте.

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

Ответ 16

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

Ответ 17

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

Вот простой пример:

public static void LogException(Exception exc, string source)
{
    try
    {
        // Logic for logging exceptions
    }
    catch(Exception ex)
    {
        //If logging fails  for some reason 
        //then we still log it using reflection
        LogException(ex, "Error while logging an exception");
    }
}