Шрифт:
Эта программа дает следующий результат. Анализ методов, определенных в классе MyClass Поддерживаемые методы: Int32 Sum Boolean IsBetween(Int32 i) Void Set(Int32 a, Int32 b) Void Set(Double a, Double b) Void Show String ToString Boolean Equals(Object obj) Int32 GetHashCode Type GetType
Как видите, помимо методов, определенных в классе MyClass, в данной программе выводятся также методы, определенные в классе object, поскольку все типы данных в C# наследуют от класса object. Кроме того, в качестве имен типов указываются имена структуры .NET. Обратите также внимание на то, что метод Set выводится дважды, поскольку он перегружается. Один из его вариантов принимает аргументы типа int, а другой — аргументы типа double.
Рассмотрим эту программу более подробно. Прежде всего следует заметить, что в классе MyClass определен открытый конструктор и ряд открытых методов, в том числе и перегружаемый метод Set.
Объект класса Туре, представляющий класс MyClass, создается в методе Main в следующей строке кода. Type t = typeof(MyClass); // получить объект класса Туре, // представляющий класс MyClass
Напомним, что оператор typeof возвращает объект класса Туре, представляющий конкретный тип данных (в данном случае — класс MyClass).
С помощью переменной t и прикладного интерфейса Reflection API в данной программе затем выводятся сведения о методах, поддерживаемых в классе MyClass. Для этого в приведенной ниже строке кода сначала выводится список соответствую щих методов. MethodInfo[] mi = t.GetMethods;
Затем в цикле foreach организуется обращение к элементам массива mi. На каж дом шаге этого цикла выводится возвращаемый тип, имя и параметры отдельного ме тода, как показано в приведенном ниже фрагменте кода. foreach(MethodInfo m in mi) { // Вывести возвращаемый тип и имя каждого метода. Console.Write(" " + m.ReturnType.Name + " " + m.Name + "("); // Вывести параметры. ParameterInfo[] pi = m.GetParameters; for(int i=0; i < pi.Length; i++) { Console.Write(pi[i].ParameterType.Name + " " + pi[i].Name); if(i+1 < pi.Length) Console.Write(", "); } }
В этом фрагменте кода параметры, связанные с каждым методом, сначала создают ся с помощью метода GetParameters и сохраняются в массиве pi. Затем в цикле for происходит обращение к элементам массива pi и выводится тип и имя каждо го параметра. Самое главное, что все эти сведения создаются динамически во время выполнения программы, не опираясь на предварительную осведомленность о классе MyClass. Вторая форма метода GetMethods
Существует вторая форма метода GetMethods, позволяющая указывать различ ные флажки для отфильтровывания извлекаемых сведений о методах. Ниже приведе на эта общая форма метода GetMethods. MethodInfo[] GetMethods(BindingFlags флажки)
В этом варианте создаются только те методы, которые соответствуют указанным критериям. BindingFlags представляет собой перечисление. Ниже перечислен ряд наиболее часто используемых его значений. Значение Описание DeclaredOnly Извлекаются только те методы, которые определены в заданном классе. Унаследованные методы в извлекаемые сведения не включаются Instance Извлекаются методы экземпляра NonPublic Извлекаются методы, не являющиеся открытыми Public Извлекаются открытые методы Static Извлекаются статические методы
Два или несколько флажков можно объединить с помощью логической операции ИЛИ. Но как минимум флажок Instance или Static следует указывать вместе с флажком Public или NonPublic. В противном случае не будут извлечены сведения ни об одном из методов.
Форма BindingFlags метода GetMethods чаще всего применяется для полу чения списка методов, определенных в классе, без дополнительного извлечения на следуемых методов. Это особенно удобно в тех случаях, когда требуется исключить по лучение сведений о методах, определяемых в классе конкретного объекта. В качестве примера попробуем выполнить следующую замену в вызове метода GetMethods из предыдущей программы. // Теперь получаются сведения только о тех методах, // которые объявлены в классе MyClass. MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
После этой замены программа дает следующий результат. Анализ методов, определенных в классе MyClass Поддерживаемые методы: Int32 Sum Boolean IsBetween(Int32 i) Void Set(Int32 a, Int32 b) Void Set(Double a, Double b) Void Show
Как видите, теперь выводятся только те методы, которые явно определены в классе MyClass. Вызов методов с помощью рефлексии
Как только методы, поддерживаемые определенным типом данных, становятся из вестны, их можно вызывать. Для этой цели служит метод Invoke, входящий в со став класса MethodInfo. Ниже приведена одна из форм этого метода: object Invoke(object obj, object[] parameters)
где obj обозначает ссылку на объект, для которого вызывается метод. Для вызова стати ческих методов (static) в качестве параметра obj передается пустое значение (null). Любые аргументы, которые должны быть переданы методу, указываются в массиве parameters. Если же аргументы не нужны, то вместо массива parameters указыва ется пустое значение (null). Кроме того, количество элементов массива parameters должно точно соответствовать количеству передаваемых аргументов. Так, если требует ся передать два аргумента, то массив parameters должен состоять из двух элементов, но не из трех или четырех. Значение, возвращаемое вызываемым методом, передается методу Invoke, который и возвращает его.