MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly |
BindingFlags.Instance | BindingFlags.Public);
// Вызвать каждый метод,
foreach (MethodInfo m in mi) {
Console.WriteLine("Вызов метода {0} ", m.Name);
// Получить параметры.
ParameterInfo[] pi = m.GetParameters();
// Выполнить методы,
switch (pi.Length) {
case 0: // аргументы отсутствуют
if (m.ReturnType == typeof(int)) {
val = (int)m.Invoke(reflectOb, null);
Console.WriteLine("Результат: " + val);
}
else if (m.ReturnType == typeof(void)) {
m.Invoke(reflectOb, null);
}
break;
case 1: // один аргумент
if (pi[0].ParameterType == typeof(int)) {
object[] args = new object[1];
args[0] = 14;
if ((bool)m.Invoke(reflectOb, args))
Console.WriteLine("Значение 14 находится между x и у");
else
Console.WriteLine("Значение 14 не находится между х и у");
}
break;
case 2: // два аргумента
if ((pi[0].ParameterType == typeof(int)) &&
(pi[1].ParameterType == typeof(int))) {
object[] args = new object[2];
args[0] = 9;
args[1] = 18;
m.Invoke(reflectOb, args);
}
else if ((pi[0].ParameterType == typeof(double)) &&
(pi[1].ParameterType == typeof(double))) {
object[] args = new object[2];
args[0] = 1.12;
args[1] = 23.4;
m.Invoke(reflectOb, args);
}
break;
}
Console.WriteLine();
}
}
}
Эта программа дает следующий результат.
Использовано: MyClass
Конструирование класса MyClass(int).
Значение х: 10, значение у: 10
Вызов методов для объекта reflectOb.
Вызов метода Sum
Результат: 20
Вызов метода IsBetween
Значение 14 не находится между х и у
Вызов метода Set
В методе Set (int, int). Значение х: 9, значение у: 18
Вызов метода Set
В методе Set(double, double). Значение х: 1, значение у: 23
Вызов метода Show
Значение х: 1, значение у: 23
Эта программа работает довольно просто, но все же требует некоторых пояснений. Во-первых, получаются и используются только те методы, которые явно объявлены в классе MyClass. Для этой цели служит форма BindingFlagsметода GetMethods(), чтобы воспрепятствовать вызову методов, наследуемых от объекта. И во-вторых, количество параметров и возвращаемый тип каждого метода получаются динамически, а затем определяются и проверяются в операторе switch. На основании этой информации формируется вызов каждого метода.
В C# разрешается вводить в программу информацию декларативного характера в форме атрибута , с помощью которого определяются дополнительные сведения (метаданные), связанные с классом, структурой, методом и т.д. Например, в программе можно указать атрибут, определяющий тип кнопки, которую должен отображать конкретный класс. Атрибуты указываются в квадратных скобках перед тем элементом, к которому они применяются. Следовательно, атрибут не является членом класса, но обозначает дополнительную информацию, присоединяемую к элементу.
Основы применения атрибутов
Атрибут поддерживается классом, наследующим от класса System.Attribute. Поэтому классы атрибутов должны быть подклассами класса Attribute. В классе Attributeопределены основные функциональные возможности, но далеко не все они нужны для работы с атрибутами. В именах классов атрибутов принято употреблять суффикс Attribute. Например, ErrorAttribute— это имя класса атрибута, описывающего ошибку.
При объявлении класса атрибута перед его именем указывается атрибут AttributeUsage. Этот встроенный атрибут обозначает типы элементов, к которым может применяться объявляемый атрибут. Так, применение атрибута может ограничиваться одними методами.
Создание атрибута
В классе атрибута определяются члены, поддерживающие атрибут. Классы атрибутов зачастую оказываются довольно простыми и содержат небольшое количество полей или свойств. Например, атрибут может определять примечание, описывающее элемент, к которому присоединяется атрибут. Такой атрибут может принимать следующий вид.
Читать дальше