Шилдт Герберт
Шрифт:
object[] GetCustomAttributes(bool наследование)
Если наследование имеет логическое значение true, то в список включаются атрибуты всех базовых классов, наследуемых по иерархической цепочке. В противном случае атрибуты извлекаются только из тех классов, которые определяются указанным типом.
Второй метод, GetCustomAttribute , определяется в классе Attribute. Ниже приведена одна из его форм:
static Attribute GetCustomAttribute(Memberlnfо элемент, Туре тип_атрибута)
где элемент обозначает объект класса Member Inf о, описывающий тот элемент, для которого создаются атрибуты, тогда как тип_атрибута — требуемый атрибут. Данный метод используется в том случае, если цмя получаемого атрибута известно заранее, что зачастую и бывает. Так, если в классе UseAttrib имеется атрибут RemarkAttribute, то для получения ссылки на этот атрибут можно воспользоваться следующей последовательностью кода.
// Получить экземпляр объекта класса MemberInfо, связанного // с классом, содержащим атрибут RemarkAttribute.
Type t = typeof(UseAttrib);
// Извлечь атрибут RemarkAttribute.
Type tRemAtt = typeof(RemarkAttribute);
RemarkAttribute ra = (RemarkAttribute)
Attribute.GetCustomAttribute(t, tRemAtt);
Эта последовательность кода оказывается вполне работоспособной, поскольку класс Memberlnfo является базовым для класса Туре. Следовательно, t — это экземпляр объекта класса Memberlnfo.
Имея ссылку на атрибут, можно получить доступ к его членам. Благодаря этому информация об атрибуте становится доступной для программы, использующей элемент, к которому присоединен атрибут. Например, в следующей строке кода выводится содержимое свойства Remark.
Console.WriteLine(га.Remark);
Ниже приведена программа, в которой все изложенные выше особенности применения атрибутов демонстрируются на примере атрибута RemarkAttribute.
// Простой пример применения атрибута.
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.All)] public class RemarkAttribute : Attribute {
string pri_remark; // базовое поле свойства Remark
public RemarkAttribute(string comment) { pri_remark = comment;
}
public string Remark {
get { ,
return pri_remark;
}
}
}
[RemarkAttribute("В этом классе используется атрибут.")] class UseAttrib {
// ...
}
class AttribDemo { static void Main {
Type t = typeof(UseAttrib);
Console.Write("Атрибуты в классе " + t.Name + ": ");
object[] attribs = t.GetCustomAttributes(false); foreach(object о in attribs) {
Console .WriteLine (о).;
}
Console.Write("Примечание: ");
// Извлечь атрибут RemarkAttribute.
Type tRemAtt = typeof(RemarkAttribute);
RemarkAttribute ra = (RemarkAttribute)
Attribute.GetCustomAttribute(t, tRemAtt);
Console.WriteLine(ra.Remark);
}
}
Эта программа дает следующий результат.
Атрибуты в классе UseAttrib: RemarkAttribute Примечание: В этом классе используется атрибут.
Сравнение позиционных и именованных параметров
В предыдущем примере для инициализации атрибута RemarkAttribute его конструктору была передана символьная строка с помощью обычного синтаксиса конструктора. В этом случае параметр comment конструктора RemarkAttribute называется позиционным. Этот термин отражает тот факт, что аргумент связан с параметром по его позиции в списке аргументов. Следовательно, первый аргумент передается первому параметру, второй аргумент — второму параметру и т.д.