русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Реализация отражения. Type, InvokeMember, BindingFlags


Дата добавления: 2015-07-09; просмотров: 1047; Нарушение авторских прав


Раннее связывание – деятельность, выполняемая на стадии компиляции, позволяющая:

§ обнаружить и идентифицировать объявленные в приложении типы,

§ выявить и идентифицировать члены класса,

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

 

Позднее, динамическое связывание – деятельность, выполняемая непосредственно при выполнении приложения, позволяющая:

§ обнаружить и идентифицировать объявленные в приложении типы,

§ выявить и идентифицировать члены класса,

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

 

При этом вызов методов и свойств при выполнении приложения обеспечивается методом InvokeMember. Этот метод выполняет достаточно сложную работу и поэтому нуждается в изощрённой системе управления, для реализации которой применяется перечисление BindingFlags. Перечисление также применяется для управления методом GetMethod.

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

 

Список элементов перечисления прилагается.

Имя элемента Описание
CreateInstance   Определяет, что отражение должно создавать экземпляр заданного типа. Вызывает конструктор, соответствующий указанным аргументам. Предоставленное имя пользователя не обрабатывается. Если тип поиска не указан, будут использованы флаги (Instance | Public). Инициализатор типа вызвать нельзя.
DeclaredOnly   Определяет, что должны рассматриваться только члены, объявленные на уровне переданной иерархии типов. Наследуемые члены не учитываются.
Default   Определяет отсутствие флагов связывания.
ExactBinding   Определяет, что типы представленных аргументов должно точно соответствовать типам соответствующих формальных параметров. Если вызывающий оператор передает непустой объект Binder, отражение создает исключение, так как при этом вызывающий оператор предоставляет реализации BindToXXX, которые выберут соответствующий метод. Отражение моделирует правила доступа для системы общих типов. Например, если вызывающий оператор находится в той же сборке, ему не нужны специальные разрешения относительно внутренних членов. В противном случае вызывающему оператору потребуется ReflectionPermission. Этот метод применяется при поиске защищенных, закрытых и т. п. членов. Главный принцип заключается в том, что ChangeType должен выполнять только расширяющее преобразование, которое никогда не теряет данных. Примером расширяющего преобразования является преобразование 32-разрядного целого числа со знаком в 64-разрядное целое число со знаком. Этим оно отличается от сужающего преобразования, при котором возможна потеря данных. Примером сужающего преобразования является преобразование 64-разрядного целого числа со знаком в 32-разрядное целое число со знаком. Связыватель по умолчанию не обрабатывает этот флаг, но пользовательские связыватели используют семантику этого флага.
FlattenHierarchy   Определяет, что должны быть возвращены статические члены вверх по иерархии. Статические члены — это поля, методы, события и свойства. Вложенные типы не возвращаются.
GetField   Определяет, что должно возвращаться значение указанного поля.
GetProperty   Определяет, что должно возвращаться значение указанного свойства.
IgnoreCase   Определяет, что при связывании не должен учитываться регистр имени члена.
IgnoreReturn   Используется при COM-взаимодействии для определения того, что возвращаемое значение члена может быть проигнорировано.
Instance   Определяет, что в поиск должны быть включены члены экземпляра.
InvokeMethod   Определяет, что метод должен быть вызван. Метод не может быть ни конструктором, ни инициализатором типа.
NonPublic   Определяет, что в поиск должны быть включены члены экземпляра, не являющиеся открытыми (public).
OptionalParamBinding   Возвращает набор членов, у которых количество параметров соответствует количеству переданных аргументов. Флаг связывания используется для методов с параметрами, у которых есть значения методов, и для функций с переменным количеством аргументов (varargs). Этот флаг должен использоваться только с Type.InvokeMember. Параметры со значениями по умолчанию используются только в тех вызовах, где опущены конечные аргументы. Они должны быть последними аргументами.
Public   Определяет, что открытые (public) члены должны быть включены в поиск.
PutDispProperty   Определяет, что для COM-объекта должен быть вызван член PROPPUT. PROPPUT задает устанавливающую свойство функцию, использующую значение. Следует использовать PutDispProperty, если для свойства заданы и PROPPUT, и PROPPUTREF и нужно различать вызываемые методы.
PutRefDispProperty   Определяет, что для COM-объекта должен быть вызван член PROPPUTREF. PROPPUTREF использует устанавливающую свойство функцию, использующую ссылку, вместо значения. Следует использовать PutRefDispProperty, если для свойства заданы и PROPPUT, и PROPPUTREF и нужно различать вызываемые методы.
SetField   Определяет, что должно устанавливаться значение указанного поля.
SetProperty   Определяет, что должно устанавливаться значение указанного свойства. Для COM-свойств задание этого флага связывания эквивалентно заданию PutDispProperty и PutRefDispProperty.
Static   Определяет, что в поиск должны быть включены статические члены.
SuppressChangeType   Не реализован.

 



Далее демонстрируется применение класса Type, в частности, варианты использования метода-члена класса Type InvokeMember, который обеспечивает выполнения методов и свойств класса.

 

using System;

using System.Reflection;

 

// В классе объявлены поле myField, конструктор, метод String ToString(), свойство.

class MyType

{

int myField;

public MyType(ref int x)

{

x *= 5;

}

 

public override String ToString()

{

Console.WriteLine(“This is: public override String ToString() method!”);

return myField.ToString();

}

 

// Свойство MyProp нашего класса обладает одной замечательной особенностью:

// значение поля myField объекта-представителя класса MyType не может быть

// меньше нуля. Если это ограничение нарушается - возбуждается исключение.

public int MyProp

{

get

{

return myField;

}

set

{

if (value < 1)

throw new ArgumentOutOfRangeException(“value”, value, “value must be > 0”);

myField = value;

}

}

}

 

class MyApp

{

static void Main()

{

 

// Создали объект-представитель класса MyType

// на основе объявления класса MyType.

Type t = typeof(MyType);

 

// А это одномерный массив объектов, содержащий ОДИН элемент.

// В этом массиве будут передаваться параметры конструктору.

Object[] args = new Object[] {8};

Console.WriteLine(“The value of x before the constructor is called is {0}.”, args[0]);

 

// Вот таким образом в рамках технологии отражения производится

// обращение к конструктору. Наш объект адресуется по ссылке obj.

Object obj = t.InvokeMember(

null,

//____________________________

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.NonPublic |

BindingFlags.Instance |

BindingFlags.CreateInstance, // Вот распоряжение о создании объекта…

//____________________________

null,

null,

args // А так организуется передача параметров в конструктор.

);

 

Console.WriteLine(“Type: ” + obj.GetType().ToString());

Console.WriteLine(“The value of x after the constructor returns is {0}.”, args[0]);

// Изменение (запись и чтение) значения поля myField. Только что созданного

// объекта-представителя класса MyType. Как известно, этот объект адресуется по

// ссылке obj. Мы сами его по этой ссылке расположили!

t.InvokeMember(

“myField”, // Будем менять значение поля myField…

//______________________________

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.NonPublic |

BindingFlags.Instance |

BindingFlags.SetField, // Вот инструкция по изменению значения поля.

//_______________________________

null,

obj, // Вот указание на то, ГДЕ располагается объект…

new Object[] {5} // А вот и само значение. Оно упаковывается в массив объектов.

);

 

int v = (Int32) t.InvokeMember(

“myField”,

//______________________________

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.NonPublic |

BindingFlags.Instance |

BindingFlags.GetField, // А сейчас мы извлекаем значение поля myField.

//______________________________

null,

obj, // “Работаем” всё с тем же объектом. Значение поля myField

// присваивается переменной v.

null

);

 

// Вот распечатали это значение.

Console.WriteLine(“myField: ” + v);

// “От имени” объекта будем вызывать нестатический метод.

String s = (String) t.InvokeMember(

“ToString”, // Имя переопределённого виртуального метода.

//______________________________

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.NonPublic |

BindingFlags.Instance |

BindingFlags.InvokeMethod, // Сомнений нет! Вызываем метод!

//______________________________

null,

obj, // От имени нашего объекта вызываем метод без параметров.

null

);

 

// Теперь обращаемся к свойству.

Console.WriteLine(“ToString: “ + s);

// Изменение значения свойства. Пытаемся присвоить недозволенное значение.

// И посмотрим, что будет… В конце-концов, мы предусмотрели перехватчик исключения.

try

{

t.InvokeMember(

“MyProp”, // Работаем со свойством.

//______________________________

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.NonPublic |

BindingFlags.Instance |

BindingFlags.SetProperty, // Установить значение свойства.

//______________________________

null,

obj,

new Object[] {0} // Вот пробуем через обращение к свойству

// установить недозволенное значение.

);

}

catch (TargetInvocationException e)

{

// Фильтруем исключения... Реагируем только на исключения типа

// ArgumentOutOfRangeException. Все остальные «проваливаем дальше».

if (e.InnerException.GetType() != typeof(ArgumentOutOfRangeException)) throw;

// А вот как реагируем на ArgumentOutOfRangeException.

// Вот так скромненько уведомляем о попытке присвоения запрещённого значения.

Console.WriteLine(“Exception! Catch the property set.”);

}

 

t.InvokeMember(

“MyProp”,

//______________________________

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.NonPublic |

BindingFlags.Instance |

BindingFlags.SetProperty, // Установить значение свойства.

//______________________________

null,

obj,

new Object[] {2} // Вновь присваиваемое значение. Теперь ПРАВИЛЬНОЕ.

);

 

v = (int) t.InvokeMember(

“MyProp”,

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.NonPublic |

BindingFlags.Instance |

BindingFlags.GetProperty, // Прочитать значение свойства.

null,

obj,

null

);

 

Console.WriteLine(“MyProp: “ + v);

}

}

 

Ну вот. Создавали объект, изменяли значение его поля (данного-члена), вызывали его (нестатический) метод, обращались к свойству (подсовывали ему некорректные значения). И при этом НИ РАЗУ НЕ НАЗЫВАЛИ ВЕЩИ СВОИМИ ИМЕНАМИ! В сущности, ЭТО И ЕСТЬ ОТРАЖЕНИЕ.

 



<== предыдущая лекция | следующая лекция ==>
Рефлексия (отражение) типов | Атрибуты


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 1.733 сек.