C#: кто-то может объяснить практичность отражения? [дубликат]

Чтобы загрузить файл в словарь с помощью модуля json, json.load возьмет дескриптор файла:

import json

with open('yourfile.json') as fh:
    val = json.load(fh)

type(val)
dict

# to get the structure you're looking for
val1 = val.get('a')

type(val1)
list
# Now you can iterate over it, or throw it into pandas if you want a
# table-like data structure

val1[0].keys()
dict_keys(['Name', 'number', 'defaultPrice', 'prices'])

Используя ваш строковый подход

Вы можете сделать это с использованием строкового подхода, который есть у вас в исходном сообщении:

import json

with open('yourfile.json') as fh:
    mystr = fh.read()

# Note, this is json.loads, which takes a string arg not a file handle
val = json.loads(mystr)

val
{'a': [{'Name': 'name1', 'number': 'number1', 'defaultPrice': {'p': '232', 'currency': 'CAD'}, 'prices': {'DZ': {'p': '62', 'currency': 'RMB'}, 'AU': {'p': '73', 'currency': 'AUD'}, 'lg': 'en'}}, {'Name': 'name2', 'number': 'number2', 'defaultPrice': {'p': '233', 'currency': 'CAD'}, 'prices': {'DZ': {'p': '63', 'currency': 'RMB'}, 'US': {'p': '72', 'currency': 'USD'}, 'Lg': 'en'}}]}

type(val)
dict


# To put this into pandas

import pandas as pd

val1 = val.get('a')

df = pd.DataFrame(val1)

Где df выглядит так:

    Name                        ...                                                                     prices
0  name1                        ...                          {'DZ': {'p': '62', 'currency': 'RMB'}, 'AU': {...
1  name2                        ...                          {'DZ': {'p': '63', 'currency': 'RMB'}, 'US': {...

[2 rows x 4 columns]

Панды будут вменять имена столбцов в качестве ключей в списке словарей

18
задан George Stocker 7 April 2009 в 20:46
поделиться

18 ответов

Отражение обеспечивает способность определить вещи и выполнить код во времени выполнения.

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

Например:

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

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

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

d) Отражение помогает Вам уменьшить шаблонный код.

e) Отражение удобно для определения мини-Предметно-ориентированных языков (DSL) в Вашем коде.

14
ответ дан 30 November 2019 в 06:07
поделиться

Можно ли отправить некоторый пример кода, который показывает, как Вы выполняете отражение? У Вас есть файлы PDB в том же месте как блок, на котором Вы используете API Reflection? Если так, затем в Visual Studio входят в меню Debug-> Исключения и проверяют флажок "Common Language runtime thrown". Запустите свое приложение в режиме отладки. Надо надеяться, отладчик должен повредиться в точке в Вашем отраженном блоке, при котором выдается реальное исключение.

0
ответ дан 30 November 2019 в 06:07
поделиться

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

0
ответ дан 30 November 2019 в 06:07
поделиться

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

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

0
ответ дан 30 November 2019 в 06:07
поделиться

Практическое применение

Используйте отражение для выравнивания Данных с объектами, как в ситуации с отображением данных. Например, можно отобразить столбец базы данных на свойство объекта. Если бы необходимо было записать Объектный Реляционный Картопостроитель, то Вам был бы нужен некоторый способ добраться от параметра конфигурации (т.е. DatabaseColumnName отображается на Класс. MemberName) к объектам, к который это обращение.

1
ответ дан 30 November 2019 в 06:07
поделиться

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

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

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

0
ответ дан 30 November 2019 в 06:07
поделиться

Я использовал отражение для реализации пользовательской системы привязки данных.

Например, с моей привязкой API я могу записать следующее:

Связывая b = новая Привязка (текстовое поле, "текст", myObject, "текст", BindingMode. Двунаправленный);

Любые изменения в тексте в объекте текстового поля обнаруживаются Объектом привязки (который присоединяет к событию TextChanged), и передал в myObject. Текстовое свойство. Изменения в myObject. Текст обнаруживается (его событием TextChanged) и передается в текстовое поле. Текстовый участник.

Я реализовал эту систему с помощью отражения. Обязательный конструктор объявляется как:

Связывая (объект, строка, объект, строка, BindingMode)

Система поэтому работает с любым объектом (с одним важным условием).

Я осматриваю первый объект и нахожу участника, соответствующего именованному участнику в первой строке (текстовое поле и "текст", т.е. делает текстовое поле, имеют участника, названного "текстом"). Повторитесь со вторым объектом и строкой.

Условие: чтобы объекты использовались в этой схеме, они должны реализовать неофициальное требование, чтобы любое связываемое свойство имело соответствующее событие PropertyNameChanged. Счастливо, в значительной степени все компоненты.Net UI следуют этой конвенции.

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

NB. Я реализовал это в.Net 1.0, таким образом, он предшествует реализации привязки Microsoft - который я еще не вернулся к исследованию.

1
ответ дан 30 November 2019 в 06:07
поделиться

Если Вы работаете быстрый и разъяренный, возможно, Вы наследовались объекту и нуждаетесь в доступе к частному полю. У Вас нет источника, но это в порядке, у Вас есть Отражение. (hacky я знаю),

Более законное использование, которое я видел, должно использовать отражение в реализации дженериков C#, где я хочу сделать некоторую операцию на универсальном типе, который не в других отношениях доступен. Единственные операции, доступные на универсальном типе, являются сделанными доступный с универсальным ограничением (т.е., если Вы вынуждаете универсальный тип реализовывать IFoo, можно использовать методы IFoo на экземплярах того класса). Некоторые операции, хотя просто не доступны - например, я посещал универсальный урок, который, как предполагалось, имел конкретного конструктора не по умолчанию. Я не мог ограничить общий метод только принять универсальные параметры типа с тем конструктором, но по крайней мере я мог попытаться использовать того конструктора при реализации дженерика через отражение.

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

2
ответ дан 30 November 2019 в 06:07
поделиться

Другие люди ответили за

что является отражением, почему это важный

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

Как я использую его?

Через следующие пространства имен

Почему я использую его?

Вызвать/осмотреть типы блока, участников, свойства

При рассмотрении продукта как Отражатель способность осмотреть структуру кода более, чем достаточно практична.

2
ответ дан 30 November 2019 в 06:07
поделиться

Скажем, у Вас есть некоторые предприятия, которые все прибывают, происходят из базового класса под названием Объект. Давайте также скажем, что Вы нуждаетесь/хотите во всех производных классах, чтобы быть cloneable. Можно реализовать метод "Клон" (интерфейс ICloneable) на базовом классе, который циклично выполнился бы через все свойства текущего класса (хотя он реализован в классе Объекта), и скопируйте их в клонированный объект. Это - случай, где Отражение может действительно помочь. Поскольку Вы не можете знать имя и количество свойств в базовом классе. И Вы не хотите реализовывать метод во всех производных классах. Однако Вы могли бы хотеть сделать метод виртуальным.

2
ответ дан 30 November 2019 в 06:07
поделиться

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

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

2
ответ дан 30 November 2019 в 06:07
поделиться

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

Рассмотрите систему плагинов, в которой хост не знает о плагинах, которые он будет содержать; с Отражением (и корректная архитектура), можно создать простое решение, достигающее этого.

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

Существует много других использований, но я надеюсь что эти два, открываю Ваш аппетит для этой превосходной функции CLR

4
ответ дан 30 November 2019 в 06:07
поделиться

Отражение использует код для исследования самого кода. Например, вместо вызова foo.DoBar() Вы могли звонить:

foo.GetType().GetMethod("DoBar").Invoke(foo,null);

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

Для получения дополнительной информации проверьте раздел MSDN по Отражению.

3
ответ дан 30 November 2019 в 06:07
поделиться

Иногда полезно смочь считать свойства или вызвать методы класса, не зная, какие свойства или методы класс имеет во время проектирования. Способ выполнить это с отражением. Как продемонстрировано кодом ниже, можно получить список всех свойств на классе и получить их значения, ничего не зная об этом во время компиляции. Или можно получить метод по имени, даже если Вы не знаете название метода во время компиляции и вызываете его через отражение. Это позволило бы Вам, например, создавать язык сценариев, который воздействует на объекты, определенные в другом предоставленном пользователями DLL. (Конечно, можно также перечислить все методы в классе или получить определенное свойство по имени, но эти случаи не продемонстрированы в коде ниже.)

class Program
{
  static void Main(string[] args)
  {
     UserDefinedClass udc = new UserDefinedClass();
     udc.UserProperty = "This is the property value";

     ClassTracer ct = new ClassTracer(udc);
     ct.TraceProperties();
     ct.CallMethod("UserFunction", "parameter 1 value");
  }
}

class ClassTracer
{
  object target;

  public ClassTracer(object target)
  {
     this.target = target;
  }

  public void TraceProperties()
  {
     // Get a list of all properties implemented by the class
     System.Reflection.PropertyInfo[] pis = target.GetType().GetProperties();
     foreach (System.Reflection.PropertyInfo pi in pis)
     {
        Console.WriteLine("{0}: {1}", pi.Name, pi.GetValue(target, null));
     }
  }

  public void CallMethod(string MethodName, string arg1)
  {
     System.Reflection.MethodInfo mi = target.GetType().GetMethod(MethodName);
     if (mi != null)
     {
        mi.Invoke(target, new object[] { arg1 });
     }
  }
}

class UserDefinedClass
{
  private string userPropertyValue;

  public string UserProperty
  {
     get
     {
        return userPropertyValue;
     }
     set
     {
        userPropertyValue = value;
     }
  }

  public void UserFunction(string parameter)
  {
     Console.WriteLine("{0} - {1}", userPropertyValue, parameter);
  }
}
4
ответ дан 30 November 2019 в 06:07
поделиться

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

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

4
ответ дан 30 November 2019 в 06:07
поделиться

Наиболее популярный способ использования отражения является расширением того, что раньше называлось RTTI (информация о типах во время выполнения) и было, прежде всего, доменом программистов на C++.

Отражение является побочным эффектом способа, которым .NET создается и что Microsoft выбрала подвергать библиотеки, они раньше создавали Visual Studio и время выполнения .NET разработчикам за пределами Microsoft.

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

    public static IMyCompanySetting UnwrapSetting(XmlNode settingNode)
    {

        string typeName = settingNode.Attributes["type"].Value;
        string typeAssembly;
        if(settingNode.Attributes["assembly"] != null)
        {
            typeAssembly = settingNode.Attributes["assembly"].Value;
        }

        Type settingType = null;
        Assembly settingAssembly = null;
        try
        {
            // Create an object based on the type and assembly properties stored in the XML
            try
            {
                settingAssembly = Assembly.Load(typeAssembly);
                if (settingAssembly == null)
                {
                    return null;
                }
            }
            catch (Exception outerEx)
            {
                try
                {
                    settingType = GetOrphanType(typeName);
                }
                catch (Exception innerEx)
                {
                    throw new Exception("Failed to create object " + typeName + " :: " + innerEx.ToString(), outerEx);
                }
            }

            // We will try in order:
            // 1. Get the type from the named assembly.
            // 2. Get the type using its fully-qualified name.
            // 3. Do a deep search for the most basic name of the class.
            if (settingType == null && settingAssembly != null) settingType = settingAssembly.GetType(typeName);
            if (settingType == null) settingType = Type.GetType(typeName);
            if (settingType == null) settingType = GetOrphanType(typeName);
            if (settingType == null) throw new System.Exception(
                String.Format("Unable to load definition for type {0} using loosest possible binding.", typeName));
        }
        catch (Exception ex)
        {
            throw new CometConfigurationException(
                String.Format("Could not create object of type {0} from assembly {1}", typeName, typeAssembly), ex);
        }

        bool settingIsCreated = false;
        IMyCompanySetting theSetting = null;

        // If the class has a constructor that accepts a single parameter that is an XML node,
        // call that constructor.
        foreach (ConstructorInfo ctor in settingType.GetConstructors())
        {
            ParameterInfo[] parameters = ctor.GetParameters();
            if (parameters.Length == 1)
            {
                if (parameters[0].ParameterType == typeof(XmlNode))
                {
                    object[] theParams = { settingNode };
                    try
                    {
                        theSetting = (IMyCompanySetting)ctor.Invoke(theParams);
                        settingIsCreated = true;
                    }
                    catch (System.Exception ex)
                    {
                        // If there is a pre-existing constructor that accepts an XML node
                        // with a different schema from the one provided here, it will fail
                        // and we'll go to the default constructor.
                        UtilitiesAndConstants.ReportExceptionToCommonLog(ex);
                        settingIsCreated = false;
                    }
                }
            }
        }

Этот код позволяет нам создавать безграничное количество классов, которые реализуют IMyCompanySetting и сериализируют и десериализовывают себя с помощью XML. Затем учитывая блок XML, который является выводом сериализации объекта, система может возвратить его в объект, даже если сам объект из библиотеки, которую библиотека сериализации не имеет статично связанным.

Существует 3 вещи, которые отражаются, делает здесь, который был бы невозможен без него:

Загрузите блок во времени выполнения на основе его имени.

Загрузите объект из блока во времени выполнения, на основе его имени.

Назовите конструктора Object на основе подписи для объекта класса, который не известен во время компиляции.

7
ответ дан 30 November 2019 в 06:07
поделиться

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

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

pen.DrawLine()

или С отражением, я могу увидеть в первый раз, если мой объект имеет метод, названный "drawline" и если так, назовите его. (Обратите внимание, что это не фактический Отражательный синтаксис C#),

 if(pen.Methods.Contains("DrawLine"))
 {
    pen.InvokeMethod("DrawLine"))
 }

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

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

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

9
ответ дан 30 November 2019 в 06:07
поделиться

Andrew Troelsen, автор Pro C# 2008 и.NET 3.5 Платформы, определяет отражение этот путь:

Во вселенной.NET отражение является процессом исследования типа выполнения.

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

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

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


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

О единственной вещи я знаю об отражении C#, то, что это является раздражающим как ад, потому что всем моим приложениям для GUI нравится выдавать невероятно раздражающее, бессмысленное "Исключение, был брошен целью вызова" исключения в Приложении. Выполненный (новый frmMain ()); вместо того, чтобы остановиться, где настоящая проблема произошла (как показано в innerException).

Ваш оператор заставляет меня полагать, что у Вас есть немногие, если любые блоки попытки/выгоды где угодно в Вашем приложении, таким образом, что каждое исключение проникает назад к вершине стека вызовов. Если Вы используете Visual Studio 2005/2008 в режиме отладки, входите в меню Debug и выбираете Исключения... пункт меню. В диалоговом окне Исключений проверьте флажки под столбцом Thrown. Теперь, когда Вы запускаете свое приложение, и исключение выдается, отладчик повредится, где исключение выдается.

2
ответ дан 30 November 2019 в 06:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: