Обоснование отражения в C # - PullRequest
       22

Обоснование отражения в C #

10 голосов
/ 07 сентября 2008

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

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

Насколько этот код приемлем? Каковы риски? Каковы законные использования этого подхода?

Ответы [ 6 ]

8 голосов
/ 07 сентября 2008

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

Посмотрите на сетку свойств .Net - любой, кто использовал Visual Studio, будет с ней знаком. Вы можете указать его на любой объект, и он создаст простой редактор свойств. Это использует отражение, фактически большинство инструментов VS.

Посмотрите на модульные тесты - они загружаются отражением (по крайней мере, в NUnit и MSTest).

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

Единственное, что ему действительно нужно, - это утка - компилятор C # уже поддерживает это: вы можете foreach делать все, что похоже на IEnumerable, независимо от того, реализует он интерфейс или нет. Вы можете использовать синтаксис коллекции C # 3 для любого класса, у которого есть метод с именем Add.

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

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

. Код отражения .Net очень быстрый, но не такой быстрый, как был бы явный вызов.

2 голосов
/ 30 марта 2009

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

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

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

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

2 голосов
/ 07 сентября 2008

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

Пример 1: Отражая в сопоставлении OR, вы изменяете имя или тип свойства в вашей объектной модели: взрывается во время выполнения.

Пример 2: Вы находитесь в магазине SOA. Веб-сервисы полностью отделены (или вы так думаете). У них есть собственный набор сгенерированных прокси-классов, но в отображении вы решаете сэкономить некоторое время и делаете это:

ExternalColor c = (ExternalColor)Enum.Parse(typeof(ExternalColor), 
                                            internalColor.ToString());

Под покровами это тоже отражение, но сделано самим .net framework. Что произойдет, если вы решите переименовать InternalColor.Grey в InternalColor.Gray ? Все выглядит хорошо, все отлично и даже нормально работает ... пока тот день, когда какой-нибудь глупый пользователь не решит использовать серый цвет ..., в этот момент маппер взорвется.

1 голос
/ 07 сентября 2008

Я недавно использовал отражение в C # для поиска реализаций определенного интерфейса. Я написал простой интерпретатор в пакетном стиле, который просматривал «действия» для каждого шага вычисления на основе имени класса. Отражая текущее пространство имен, всплывет правильная реализация моего интерфейса IStep, который может быть Execute () ed. Таким образом, добавление новых «действий» так же просто, как создание нового производного класса - нет необходимости добавлять его в реестр или, что еще хуже: забыть добавить его в реестр ...

1 голос
/ 07 сентября 2008

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

Например, сгенерированный класс может выглядеть так:

static class AtoBCopier
{
    public static B Copy(A item)
    {
        return new B() { Prop1 = item.Prop1, Prop2 = item.Prop2 };
    }
}

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

0 голосов
/ 17 апреля 2012

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

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

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