System. Reflection – основные элементы, свойства и практика применения
Выбери формат для чтения
Загружаем конспект в формате doc
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
МИНОБРНАУКИ РОССИИ
Федеральное государственное бюджетное образовательное учреждение
высшего образования
«МИРЭА – Российский технологический университет»
РТУ МИРЭА
Институт международного образования
Кафедра КБ-4 «Автоматизация системы управления»
КУРСОВОЙ ПРОЕКТ (РАБОТА)
по дисциплине
« Программирование Информационных систем »
наименование дисциплины
Тема курсового проекта (работы) « System.Reflection – основные элементы, свойства и практика применения »
Студент группы БСБО-07-17 Чередниченко Д.Р.
(учебная группа) Фамилия И.О.
Руководитель курсового проекта (работы) Сачков В.Е.
должность, звание, ученая степень Фамилия И.О.
Работа представлена к защите «__»______ 20__г. подпись студента
Допущен к защите «__»______ 20__г.
подпись руководителя
Москва, 2021 г.
Содержание
Введение 3
1 Ключевые понятия рефлексии 4
1.1 Основные принципы 4
1.2 Рефлексия в ООП 8
2 Использование System.Reflection 11
2.1 Язык программирования и среда разработки 11
2.2 Примеры кода с использованием System.Reflection в языке C# 12
Заключение 17
Список использованных источников 18
Приложения 19
ВВЕДЕНИЕ
Рефлексия – это широкое понятие, которое изучалось во многих областях науки в целом и в области компьютерных наук в частности. Даже в узкой области языков программирования оно применяется к различным парадигмам, особенно к логическим, функциональным и объектно-ориентированным. В связи с этим использование рефлексии в различных языках программирования обеспечивает актуальность темы текущей работы.
Целью работы является обзор модуля System.Reflection в языке программирования C# и рассмотрение его ключевых особенностей. Для достижения цели в работе были поставлены следующие задачи:
• Получить общее представление о рефлексии;
• Рассмотреть возможности рефлексии в контексте объектно-ориентированной (ООП) парадигмы программирования;
• Выполнить обзор модуля System.Reflection и привести примеры его использования на языке C#.
Курсовая работа изложена на 21 странице печатного текста, состоит из введения, двух глав, заключения, а также списка использованных источников, включающего 11 наименований. Во введении обоснована актуальность темы, сформулированы цели, задачи исследования. В первой главе рассматриваются основные понятия рефлексии и ее возможности в контексте ООП. Во второй главе приводятся примеры программного кода на языке программирования C# с использованием рефлексии при помощи модуля System.Reflection. В заключении подведен итог результатов, сделаны выводы.
1 Ключевые понятия рефлексии
1.1 Основные принципы
Понятие рефлексии давно изучено в философии и в некоторой степени формализовано в логике. Оно возникло естественным образом в искусственном интеллекте, где было тесно связано с самой конечной целью: рефлексия рассматривается как возникающее свойство, ответственное, по крайней мере частично, за то, что считается «интеллектуальным поведением». Оно также применялось в области языков программирования под названием вычислительной рефлексии. Вычислительная рефлексия датируется основополагающей работой Брайана Смита в начале 80-х годов. В своем способе формализовать концепцию рефлексии он разработал два языка: 2-Лисп и 3-Лисп. Хотя Смит уделял гораздо больше внимания отношению представления, которое он назвал φ, который вычислительный процесс несет в своей предметной области, его работа быстро прославилась в функциональном сообществе благодаря способности, которую 3-Лисп дал программе – рефлексировать о собственном вычислении.
Этот подход вдохновлял на большую работу в сообществе функционального программирования до конца 80-х годов, вероятно, потому что рефлексия росла в плодородной почве. Благодаря встроенной цитатной конструкции Лисп известен своей металингвистической силой. Это позволило с самого начала манипулировать и исполнять фрагменты программы, которые являются примитивным проявлением рефлексивных понятий. Интерпретаторы Lisp также широко исследовались и обсуждались. Поэтому у сообщества Lisp был большой опыт работы с вещами, которые рефлексия хотела включить. К началу 90-х годов стало совершенно ясно, что для того, чтобы справиться с присущей сложностью полностью рефлексивного языка программирования, крайне необходимы механизмы структурирования. Объектно-ориентированная парадигма поставила перед собой задачу принять вызов.
Lisp оказал глубокое влияние на целое подмножество объектно-ориентированного сообщества, особенно то, которое вращается вокруг Smalltalk и, естественно, вокруг объектно-ориентированных расширений самого Lisp (квинтэссенция которых – Common Lisp Object System, CLOS). Реализация оригинальных концепций в этой новой парадигме оказалось достаточно новой, чтобы связать их с парадигмой функциональной. Протокол метаобъектов CLOS является наиболее совершенным рефлексивным языком программирования на сегодняшний день.
В течение долгого времени терминология и основные понятия были пятой Ахилла в вычислительной рефлексии. Как отмечалось ранее, фактическая реализация рефлексии в языках программирования использует множество методов и механизмов, которые существовали задолго до рефлексии: способность манипулировать программами как данными во время выполнения, возможность проверять структуры данных во время выполнения, метапрограммирование и т. д. В последние годы мы наблюдали тенденцию к смешению рефлексии и использованию этих методов. В некотором смысле, инструменты были взяты для создания новой концепции. Безусловно, существует связь между объектами, функциями высшего порядка, метапрограммированием и рефлексией, но никто не поддерживает другой подход.
Понятие рефлексии было определено в довольно общем виде Брайаном Смитом во время семинара ECOOP / OOPSLA'90: «Встроенная способность сущности представлять себя, выполнять действие над самой собой и иным образом обращаться с собой так же, как она представляет свой основной объект, взаимодействует и обращается с ним».
В языках программирования воплощение этого определения выглядит следующим образом: «Рефлексия – это способность программы манипулировать как данными чем-то, представляющим состояние программы во время ее собственного выполнения. Есть два аспекта таких манипуляций: самоанализ и интерцессия. Самоанализ – это способность программы наблюдать и, следовательно, рассуждать о своем собственном состоянии. Интерцессия – это способность программы изменять свое собственное состояние выполнения или изменять свою собственную интерпретацию или значение. Оба аспекта требуют механизма для кодирования состояния выполнения в качестве данных; предоставление такой кодировки называется реификацией (овеществлением)».
Реификацию следует отличать от первоклассных сущностей. Когда сущность является первоклассной в языке, это означает, что эта сущность может быть создана во время выполнения, передана в качестве фактических параметров процедурам, возвращена как результат функции и сохранена в переменной. Все, что нужно, – это предоставить программам значения подходящего абстрактного типа данных, определенного языком. В функциональных языках функции являются первоклассными. Это означает, что функции (фактически замыкания) – это значения, которыми можно манипулировать, как и любыми другими значениями в языке. Реификация выходит далеко за пределы этих понятий, предоставляя нам полный контроль над этим значением в самом языке. В частности, мы должны иметь возможность изменять его представление, используя сам язык. Мы также должны быть в состоянии проверить это во время выполнения программы. Создание сущности первого класса строго входит в ее определение, но не наоборот.
Пэтти Мэйс в своей диссертации дала следующие определения, которые довольно хорошо обобщают понятие рефлексии в вычислительных системах [2]:
1. Вычислительная система – это то, что воздействует на некоторую часть мира, называемую областью системы.
2. Вычислительная система может быть неразрывно связана с ее областью. Это означает, что система и ее область связаны таким образом, что, если одно из двух изменится, это приведет к влиянию на другое.
3. Мета-система – это вычислительная система, которая имеет в качестве своей области другую вычислительную систему, называемую ее объектной системой. Мета-система имеет представление своей объектной системы в своих данных. Ее программа называется метапрограммой.
4. Рефлексия – это процесс рассуждения о себе и / или воздействия на себя.
5. Рефлексивная система – это причинно-связанная метасистема, которая сама является объектной системой. Когда система рассуждает или действует на себя, мы говорим о рефлексивном вычислении.
Хотя мета-интерпретаторы интенсивно использовались при реализации рефлексивных систем, метапрограммирование не является рефлексией. Но обратите внимание, что в рефлексии доступ к представлению метауровня делается специально, чтобы выполнить какую-то задачу. Подход метапрограммирования дает программисту доступ к этому представлению, потому что он держит руку на мета-интерпретаторе, который он может изменить, чтобы выполнить задачу, которую он первоначально намеревался выполнить. Рефлексия – наоборот. Реализация уже существует, и к ней нет доступа, кроме как из самой программы, по рефлексии.
Метапрограммирование сыграло важную роль в реализации рефлексивных языков, потому что на практике трудно получить доступ к информации метауровня на существующем языке, где обычно реализация полностью закрыта [1]. Мета-интерпретатор интересен тем, что гораздо проще сделать его доступным для программ, которые он запускает, чем модифицировать реализацию языка.
Мэйс утверждала [2]: «Основное различие между архитектурой метауровня и рефлексивной архитектурой заключается в том, что архитектура метауровня обеспечивает только статический доступ к представлению вычислительной системы, в то время как рефлексивная архитектура также обеспечивает динамический доступ к этому представлению». Вид изменения, который мы можем сделать в метапрограммистском подходе, состоит в том, чтобы модифицировать мета-интерпретатор перед выполнением программы. Рефлексия, с другой стороны, позволяет программе изменять свое поведение во время работы в зависимости от ее текущего выполнения (например, входных данных и промежуточных результатов).
В вычислительной рефлексии традиционно проводится различие между структурной и поведенческой рефлексией. Эти два понятия определены следующим образом [1]:
1. Структурная рефлексия подразумевает способность языка обеспечивать полную реификацию как выполняемой в данный момент программы, так и полную реификацию ее абстрактных типов данных.
2. Поведенческая рефлексия подразумевает способность языка обеспечить полное уточнение собственной семантики (процессора), а также полное преобразование данных, которые он использует для выполнения текущей программы.
Различие было сделано главным образом потому, что гораздо эффективнее реализовать структурную рефлексию, чем поведенческую. Например, такие языки, как Lisp и Prolog, в течение многих лет включали некоторые особенности структурной рефлексии [5]. Соответственно, поведенческая рефлексия гораздо менее распространена, но она является основным направлением сегодняшних и будущих исследований.
1.2 Рефлексия в ООП
Две основные тенденции выделяются в истории объектно-ориентированного программирования [4]. Первая из них связана с языками Simula-67, C++, Eiffel и Beta и основана на принципах разработки программного обеспечения и модульности. Это привело к типизированным языкам и характеризуется относительно жесткой объектной моделью, чуждой рефлексивным понятиям. Вторая тенденция, рожденная в мире нетипизированных и уже частично структурно рефлексивных языков, привела к гораздо более гибким языкам, где классы обычно рассматриваются как первоклассные объекты. Эта тенденция подтверждается Smalltalk, а также объектно-ориентированными расширениями Lisp: Flavors, Loops, Ceyx и CLOS. Эта вторая тенденция играет важную роль в рефлексии.
Эволюция гибких объектно-ориентированных языков была впервые отмечена поиском правильной модели метакласса / класса / экземпляра, которая привела к полному представлению о структурной рефлексии в том, что касается объектной модели языка. Таким образом, история выглядит следующим образом. Smalltalk-72 уже включал идею, что все должно быть объектом, даже классом. Класс вводит структурную рефлексию в том смысле, что он описывает структуру объекта. Smalltalk-72 сделал классы первоклассными сущностями, но все же они рассматривались как примеры самих себя. Помимо наследования, Smalltalk-76 представил метаклассы, классы классов. Обратите внимание, что в ООП каждый объект имеет класс, который называется его классом экземпляра. Как объект, класс Smalltalk-76 имеет свой собственный класс создания экземпляров, называемый его метаклассом. Smalltalk-80 продолжил эту идею, но наложил некоторые важные ограничения на метаклассы [3]:
1. Метаклассы не имеют имен, и они обрабатываются системой таким образом, чтобы максимально скрыть их от конечного пользователя.
2. Все метаклассы являются экземплярами одного и того же класса. Метакласс, следовательно, число метауровней является фиксированным, и метассылки не могут создаваться бесконечно.
Как уже было показано, модель поведенческой рефлексии должна позволять программам вмешиваться в текущее выполнение, чтобы выполнить некоторый рефлексивный код, который будет анализировать или изменять ход событий. В функциональном программировании 3-Лисп изобрел рефлексивные процедуры для этого. В ООП вызов процедуры используется для передачи сообщений. Следовательно, естественно использовать передачу сообщений в качестве выгодных точек для рефлексии и использовать методы для представления рефлексивного кода. Выполнение сообщения делится на две фазы: фаза поиска, чтобы найти метод, который соответствует селектору сообщения, и фаза применения, которая фактически выполняет этот метод. Поведенческая рефлексия в ООП была реализована, главным образом, путем предоставления пользователю контроля над этими механизмами передачи сообщений. Это было сделано двумя разными способами [5]:
1. В традиционных языках ООП, таких как Smalltalk, механизмы передачи сообщений были усовершенствованы. Эти механизмы обычно поддерживаются мета-объектом, с которым связан объект. Каждое сообщение, отправленное объекту, затем преобразуется в последовательность из двух сообщений: сообщение поиска, отправленное метаобъекту, и метод, которому отправляется сообщение для его вызова. Рефлексивный код может быть реализован путем создания подклассов стандартных мета-объектов и переопределения метода поиска, а также путем создания подклассов стандартного класса, описывающих методы и переопределяющих метод применения.
2. В языках ООП, основанных на понятии универсальной функции, таких как CLOS, поведенческая рефлексия была введена путем изменения протокола вызова универсальной функции, в результате чего собственно функция применения стала универсальной функцией. Рефлексивный код может быть реализован путем определения подклассов стандартного класса, описывающего универсальные выражения, и путем переопределения метода применения для этих новых классов.
2 Использование System.Reflection
2.1 Язык программирования и среда разработки
C# был разработан в качестве конкурента языка Java; подразумевалось, что он будет чистым объектно-ориентированным языком программирования. C# дебютировал в 2000 году на конференции профессиональных разработчиков, где основным докладчиком был основатель Microsoft Билл Гейтс [7]. В то же время была представлена среда разработки Visual Studio .NET.
Высокоуровневый язык программирования C# является флагманом разработки от Microsoft. Это современный типобезопасный язык программирования с несколькими парадигмами, который стал очень популярным и широко распространенным для разработки благодаря своей простоте, гибкости и производительности. Тот факт, что C# извлекает выгоду из нескольких ключевых функций и мощных идей, найденных в разных языках программирования с разными парадигмами, приводит к тому, что язык можно задействовать для разработки приложений, используя чистый синтаксис Java, простоту Visual Basic, а также мощность и выразительность языков программирования C и C++ [6].
Можно выделить следующие плюсы языка C#, отличающие его от конкурентов [8]:
1. Доступность
Если для Java необходимо отдельно устанавливать виртуальную машину, то .NET-разработка требует только .NET-платформы, которая есть на большинстве компьютеров с ОС Windows. Соответственно, оптимизация исполняемого кода ложится на платформу, что облегчает жизнь разработчика.
2. Универсальность
Приложения C# функционируют на всех компьютерах с ОС Windows – притом можно указывать версию .NET Framework для работы с более ранними версиями. Среда разработки Xamarin также распространяет C# на Unix-системы, C# отныне является кроссплатформенным языком.
3. Эргономичность
Поставляемые пакеты NuGet, интерактивное взаимодействие с объектами, ADO/OLE/Entity/ASP, интеллектуальная подсказка, одно из самых широчайших и полезных сообществ.
4. Инновационность
С# стал флагманом не просто так – именно в нем реализуются многие особенности архитектуры программ, протоколов, принципов работы с памятью, структурами данных, подходов и принципов проектирования.
Возможности языка позволяют взять на себя значительные объемы рутинной работы, согласовать деятельность постановщиков, кодировщиков, тестеров и технических писателей.
Таким образом, среда визуального проектирования Visual Studio полностью отвечает поставленным требованиям и подходит для создания систем любой сложности.
Большая часть работы с проектом в среде Microsoft Visual Studio включает в себя создание кода, который объединяет все элементы вместе. VS предварительно генерирует этот код, упрощая работу программиста. После того, как весь дизайн и функциональность будут завершены, автоматически будет создан файл с расширением *.exe для запуска программы внутри и вне VS [9].
2.2 Примеры кода с использованием System.Reflection в языке C#
Рефлексия предоставляет объекты (типа Type), которые описывают сборки, модули и типы. Можно использовать рефлексию для динамического создания экземпляра типа, привязки типа к существующему объекту или получения типа из существующего объекта и вызова его методов или для доступа к его полям и свойствам. Если в программном коде используются атрибуты, рефлексия позволяет получить к ним доступ.
Пространство имен System.Reflection позволяет получать данные о загруженных сборках, элементах внутри них, таких как классы, методы и типы значений [10]. Некоторые из наиболее часто используемых классов System.Reflection с их описанием приведены в таблице 1.
Таблица 1 – Описание классов пространства имен System.Reflection
Класс
Описание
Assembly
описывает сборку, которая является многократно используемым, с изменяющейся версией и самоописывающимся блоком приложения среды CLR
AssemblyName
идентифицирует новый экземпляр класса сборки с уникальным именем
ConstructorInfo
описывает конструктор класса и предоставляет доступ к метаданным
MethodInfo
описывает метод класса и предоставляет доступ к метаданным
ParameterInfo
описывает параметры метода и предоставляет доступ к метаданным
EventInfo
описывает информацию о событии и предоставляет доступ к метаданным
PropertyInfo
описывает атрибуты свойства и предоставляет доступ к метаданным
MemberInfo
описывает информацию об атрибутах члена и предоставляет доступ к метаданным
Также в этом пространстве имен существует множество других классов, а приведенная выше таблица дает информацию о наиболее часто используемых.
Эти классы представляют составные блоки типа и приложения: методы, свойства и т.д. Но чтобы получить информацию о членах типа, надо воспользоваться классом System.Type.
Класс System.Type представляет изучаемый тип, инкапсулируя всю информацию о нем. С помощью его свойств и методов можно получить эту информацию. Некоторые из его свойств и методов [9]:
Метод FindMembers() возвращает массив объектов MemberInfo данного типа;
Метод GetConstructors() возвращает все конструкторы данного типа в виде набора объектов ConstructorInfo;
Метод GetEvents() возвращает все события данного типа в виде массива объектов EventInfo;
Метод GetFields() возвращает все поля данного типа в виде массива объектов FieldInfo;
Метод GetInterfaces() получает все реализуемые данным типом интерфейсы в виде массива объектов Type;
Метод GetMembers() возвращает все члены типа в виде массива объектов MemberInfo;
Метод GetMethods() получает все методы типа в виде массива объектов MethodInfo;
Метод GetProperties() получает все свойства в виде массива объектов PropertyInfo;
Свойство Name возвращает имя типа;
Свойство Assembly возвращает название сборки, где определен тип;
Свойство Namespace возвращает название пространства имен, где определен тип;
Свойство IsArray возвращает true, если тип является массивом;
Свойство IsClass возвращает true, если тип представляет класс;
Свойство IsEnum возвращает true, если тип является перечислением;
Свойство IsInterface возвращает true, если тип представляет интерфейс.
Простой пример рефлексии с использованием статического метода GetType, унаследованного всеми типами от базового класса Object, для получения типа переменной, приведен в листинге 1. На экран будет выведено «System.Int32».
Листинг 1. Использование GetType для получения информации о типе
int i = 42;
System.Type type = i.GetType();
System.Console.WriteLine(type);
В следующем примере (листинг 2) рефлексия используется для получения полного имени загруженной сборки. После выполнения этого фрагмента кода на экран программы (в консольном приложении) будет выведена строка, содержащая следующий набор символов: «mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089».
Листинг 2. Использование рефлексии для получения информации из сборки (Assembly)
System.Reflection.Assembly info = typeof(System.Int32).Assembly;
System.Console.WriteLine(info);
В приведенном ниже коде (листинг 3) тип t инициализируется как строка с помощью метода typeof. Затем применяется рефлексия для t с целью найти любую информацию о строковом классе, такую как его имя, полное имя, пространство имен и базовый тип.
Листинг 3. Пример рефлексии для вывода имен
// Инициализировать t как строку через typeof
Type t = typeof (string);
// Использовать рефлексию для поиска любых данных, связанных с t
Console.WriteLine ("Имя: {0}", t.Name); // будет выведено String
Console.WriteLine ("Полное имя: {0}", t.FullName); // будет выведено System.String
Console.WriteLine ("Пространство имен: {0}", t.Namespace); // будет выведено System
Console.WriteLine ("Базовый тип: {0}", t.BaseType); // будет выведено System.Object
В качестве примера использования рефлексии для класса составного типа рассмотрен исходный код программы, приведенный в приложении 1. Результат выполнения этого кода приведен на рис. 2.1.
Рис. 2.1 – Пример работы программы с рефлексией для составных типов
ЗАКЛЮЧЕНИЕ
В ходе выполнения курсовой работы были изучены различные подходы к рефлексии в трех основных парадигмах программирования: логическое, функциональное и объектно-ориентированное программирование. В первой части работы был подробно описан объектно-ориентированный (ООП) подход, а также ключевые особенности и понятии рефлексии применительно к этому подходу.
Во второй части самостоятельно были изучены функции и возможности интегрированной среды разработки Microsoft Visual Studio. Был выбран язык C# с модулем System.Reflection для реализации рефлексии в этой среде. При изучении возможностей пространства имен System.Reflection были закреплены навыки создания приложений в интегрированной среде программирования Visual Studio Community 2019. Изучение и написание программного кода с примерами рефлексии на языке программирования C# поспособствовало систематизации, закреплению и расширению знаний, полученных при изучении возможностей языка.
Таким образом, все поставленные задачи были выполнены в полном объеме, и цель курсовой работы можно считать полностью достигнутой.
Список использованных источников
1. Feferman, S. Transfinite Recursive Progressions of Axiomatic Theories. Journal of Symbolic Logic, 27:259–316, 1962
2. Maes, M. Computational Reflection. PhD thesis, Vrije Universiteit Brussel, 1987.
3. Smith, B.S. Reflection and Semantics in a Procedural Language. Tech. Report 272, MIT, 1982
4. The First Workshop on Reflection and Metalevel Architectures in Object-Oriented Programming, OOPSLA/ECOOP’90, Oct. 1990.
5. White J.L, Bobrow, R., Gabriel, P. CLOS in Context – The Shape of the Design Space. In A. Paepcke, editor, Object-Oriented Programming — The CLOS Perspective, chapter 2. MIT Press, 1993
6. Евсеева О. Н., Шамшев А. Б. «Работа с базами данных на языке C#», 2019. – 170 с.
7. Оберг Р.Д., Торстейнсон П. Архитектура .NET и программирование с помощью Visual C++ / Р.Д. Оберг, П. Торстейнсон пер.с англ. М.: Издательский дом «Вильям», 2002. – 656 с.
8. Стиллмен Э., Грин Дж. «Изучаем C#», 2012. – 696 с.
9. Рефлексия. Введение в рефлексию [Электронный ресурс] / Режим доступа: https://metanit.com/sharp/tutorial/14.1.php (дата обращения: 21.05.2021)
10. Троелсен Э. «Язык программирования C# 5.0 и платформа .NET 4.5», Вильямс, 2013. – 1312 с.
11. Шилдт Г. «C# 4.0. Полное руководство», 2010. – 1056 с.
ПРИЛОЖЕНИЯ
Приложение 1
Полный исходный код программы для рефлексии составных типов
using System;
using System.Reflection;
namespace ReflectionProject
{
///
/// Класс с описанием студента
///
class Student
{
///
/// Свойство для номера студента
///
public int Number
{
get;
set;
}
///
/// Свойство для имени студента
///
public string Name
{
get;
set;
}
///
/// Конструктор по умолчанию
///
public Student()
{
Number = 0;
Name = string.Empty;
}
///
/// Конструктор с параметрами
///
/// номер
/// имя
public Student(int num, string n)
{
Number = num;
Name = n;
}
///
/// Выводит данные о студенте на экран
///
public void PrintInfo()
{
Console.WriteLine("Номер: {0}", Number);
Console.WriteLine("Имя: {0}", Name);
}
}
class Program
{
///
/// Главная функция программы
///
///
static void Main(string[] args)
{
// Объявление экземпляра класса Assembly
// Вызов метода GetExecutingAssembly для загрузки текущей сборки
Assembly exec = Assembly.GetExecutingAssembly();
// Массив для хранения типов сборки
Type[] types = exec.GetTypes();
foreach (var type in types)
{
// Отображение каждого типа
Console.WriteLine("Класс: {0}", type.Name);
// Массив для хранения методов
MethodInfo[] methods = type.GetMethods();
foreach (var method in methods)
{
// Отображение каждого метода
Console.WriteLine("--> Метод: {0}", method.Name);
// Массив для хранения параметров
ParameterInfo[] parameters = method.GetParameters();
foreach (var p in parameters)
// Отображение каждого параметра
Console.WriteLine("----> Параметр: {0} Тип: {1}",
p.Name, p.ParameterType);
}
}
Console.ReadKey();
}
}
}