object[] args = new object [2]; args[0] = 1J12; args[l] = 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. Этот встроенный атрибут обозначает типы элементов, к которым может применяться объявляемый атрибут. Так, применение атрибута может ограничиваться одними методами.
Создание атрибута
В классе атрибута определяются члены, поддерживающие атрибут. Классы атрибутов зачастую оказываются довольно простыми и содержат небольшое количество полей или свойств. Например, атрибут может определять примечание, описывающее элемент, к которому присоединяется атрибут. Такой атрибут может принимать следующий вид.
[AttributeUsage(AttributeTargets.All) ] public class RemarkAttribute : Attribute {
string pri_remark; // базовое поле свойства Remark
public RemarkAttribute(string comment) { pri_remark = comment;
}
public string Remark { v get {
return pri_remark;
}
}
}
Проанализируем этот класс атрибута построчно.
Объявляемый атрибут получает имя RemarkAttribute. Его объявлению предшествует встроенный атрибут AttributeUsage, указывающий на то, что атрибут RemarkAttribute может применяться ко всем типам элементов. С помощью встроенного атрибута AttributeUsage можно сузить перечень элементов, к которым может присоединяться объявляемый атрибут. Подробнее о его возможностях речь пойдет далее в этой главе.
Далее объявляется класс RemarkAttribute, наследующий от класса Attribute. В классе RemarkAttribute определяется единственное закрытое поле pri_remark, поддерживающее одно открытое и доступное для чтения свойство Remark. Это свойство содержит описание, связываемое с атрибутом. (Конечно, Remark можно было бы объявить как автоматически реализуемое свойство с закрытым аксессором set, но ради наглядности данного примера выбрано свойство, доступное только для чтения.) В данном классе определен также один открытый конструктор, принимающий строковый аргумент и присваивающий его свойству Remark. Этим пока что ограничиваются функциональные возможности класса RemarkAttribute, готового к применению.