Отражение в C #? - PullRequest
       2

Отражение в C #?

5 голосов
/ 26 февраля 2011

Я недавно перешел от веб-разработчика на Java к разработчику приложений на C #, который в основном занимается приложениями WPF. Раньше я использовал Spring MVC с Java, где большая часть структуры кода была выгружена и настроена для меня. С тех пор, как я перешел на WPF, мои приложения зависят от моей способности настраивать многократно используемый, отсоединенный код.

Я пытался улучшить свои навыки в определенных областях дизайна, включая Дженерики, Шаблоны проектирования и Отражение.

Я хорошо знаю, что все это такое, и что касается шаблонов Generics и Design, я довольно хорошо применяю то, что считаю лучшими практиками (хотя это и в воздухе).

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

Что я не понимаю, так это примеры того, как это может мне помочь.

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

Мой вопрос заключается в том, на что я могу обратить внимание как на разработчика WPF при использовании рефлексии, поскольку это поможет мне, и / или есть место или ссылка, которые могут дать мне больше, чем просто синтаксис использования рефлексии, но также и реальный мировые примеры и / или лучшие практики?

Ответы [ 8 ]

4 голосов
/ 26 февраля 2011

Отражение может использоваться для таких вещей, как:

  1. ORM (объектно-реляционное отображение): отображение свойств объекта на столбцы в таблице базы данных
  2. Привязка модели: Отображение данных, публикуемых из веб-формы, в свойства объекта
  3. Копирование: Отображение бизнес-объектов в DTO
  4. Сериализация: отображение объектов в / из json или xml
  5. MVC Framework: проверка URL-адресов и создание объектов контроллеров на основе соглашения об именах
  6. Проверка: Проверка объектов на наличие атрибутов и применение правил проверки

Пример:

public class Customer : Entity
{
    [Required]
    public string Name { get; set; }
}

И затем что-то еще может искать эти атрибуты, например, валидатор:

public class Validator
{
    public ValidationResult Validate(Entity entity)
    {
        // use reflection to find validation attributes and enforce them
    }
}
4 голосов
/ 26 февраля 2011

Reflection - это мощный API.На базовом уровне отражение позволяет:

  • Проверка типов, содержащихся в сборке
  • Проверка элементов данного типа, включая метаданные (с помощью атрибутов)
  • Динамически вызывайте эти элементы

Если вы используете механизм связывания в WPF для привязки к обычным бизнес-объектам, то вы уже используете отражение.Привязка API, после поиска более формальных механизмов привязки (наследование от DependencyObject, наличие пользовательского дескриптора типа и т. Д.), Будет использовать отражение, чтобы получить и установить значения свойств вашего бизнес-объекта (или ViewModel).

Например, скажем, у вас есть этот класс

открытый класс Customer {public string Name {get;задавать;}}

И ваш элемент управления (представление) WPF привязывается к коллекции этих Customer объектов и имеет элемент управления меткой, который привязывается к свойству Name.Все это определено в XAML, но во время выполнения код будет выглядеть примерно так:

var value = dataObject.GetType().GetProperty("Name").GetValue(dataObject, null);

Это позволит получить значение из связанного объекта - ничего не зная о его типе - и разрешитьконтроль, чтобы отобразить его соответствующим образом.Аналогично:

dataObject.GetType().GetProperty("Name").SetValue(dataObject, "Bob", null);

установит значение свойства этого объекта равным "Bob", опять же, ничего не зная о его типе.

Что касается того, как оно может помочь вам непосредственно , варианты использования для этого сравнительно редки.Если вы оказались в положении, когда нужно , чтобы использовать рефлексию для достижения того, что вам нужно, вы можете рассмотреть возможность рефакторинга кода;всегда лучше (в языке со статической типизацией, таком как C #) идти с кодом, который следует за статической типизацией, вместо использования динамического вызова через отражение.Хотя проверка метаданных довольно дешевая, для вызова члена с помощью отражения требуется намного больше обработки, чем обычным способом.

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

3 голосов
/ 26 февраля 2011

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

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

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

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

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

2 голосов
/ 26 февраля 2011

Отражение полезно для библиотеки кода, который не может знать о реальных типах.Хорошим примером является упомянутый вами WPF;как вы думаете, он разрешает строки в свойствах xaml?И привязки данных внутри xaml?

Классические примеры:

  • привязка данных
  • сериализация
  • ORM - базы данных <===> классов
  • IDE / инструменты разработки / редакторы
  • метапрограммирование

В вашем использовании WPF используется не менее 3 из них;вероятно, 4, если вы используете базу данных

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

2 голосов
/ 26 февраля 2011

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

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

Пример:

//Without reflection
Foo foo = new Foo();
foo.Hello();

//With reflection
object foo = Activator.CreateInstance(null, "Foo");
foo.GetType().GetMethod("Hello").Invoke(foo, null);

Отражение также можно использовать для динамической адаптации данной программы к различным ситуациям.Например, рассмотрим приложение, которое использует два разных класса X и Y взаимозаменяемо для выполнения аналогичных операций.Без программирования, ориентированного на отражение, приложение может быть жестко запрограммировано для вызова имен методов класса X и класса Y. Однако, используя парадигму программирования, ориентированного на отражение, приложение может быть спроектировано и написано для использования отражения, чтобы вызывать методы вклассы X и Y без жесткого кодирования имен методов.Ориентированное на отражение программирование почти всегда требует дополнительных знаний, структуры, реляционного отображения и релевантности объектов, чтобы воспользоваться преимуществами более общего выполнения кода.Жесткого кодирования можно избежать, если используется программирование, ориентированное на отражение.

Источник: Википедия

Считается выглядящим Документы MSDN ..у них есть обширная информация и примеры по этой теме.

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

1 голос
/ 26 февраля 2011

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

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

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

1 голос
/ 26 февраля 2011

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

Самой последней проблемой, которую мне пришлось решить с помощью отражения, был пользовательский XMLSerializer / Deserializer, в котором II имел некоторую аннотацию строкового типа и строковое значение и использовал отражение для повторного создания и экземпляра типа (или списка типов) из указанное строковое значение во время выполнения. Это требуется

  1. Activator.CreateInstance() для создания экземпляра универсального списка типа
  2. Отражение и использование TypeConverter для создания экземпляр типа примитива
  3. Отражение и использование MethodInfo, чтобы добавить примитивный тип к списку, используя универсальный метод во время выполнения.

Ищите проблему в хорошо проработанном пространстве, которое требует отражения, а затем просто приступайте к ее изучению, делая!

1 голос
/ 26 февраля 2011

Я могу привести вам пример здесь. Предположим, что у вас есть форма со всеми данными сотрудника. Предположим, что у вас есть объект класса employee, будут заполнены все свойства.

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

Здесь я использовал отражение.

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

Пожалуйста, дайте мне знать, если у вас есть еще сомнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...