C# is a procedural language, but like all procedural languages it does have some declarative elements. For example, the accessibility of a method in a class is specified by decorating it public
, protected
, internal
, protected internal
, or private
. Through its support for attributes, C# generalizes this capability, so that programmers can invent new kinds of declarative information, specify this declarative information for various program entities, and retrieve this declarative information at run-time. Programs specify this additional declarative information by defining and using attributes.
For instance, a framework might define a HelpAttribute
attribute that can be placed on program elements such as classes and methods to provide a mapping from program elements to documentation for them. The example
[AttributeUsage(AttributeTargets.All)] public class HelpAttribute: System.Attribute { public HelpAttribute(string url) { this.url = url; } public string Topic = null; private string url; public string Url { get { return url; } } }
defines an attribute class named HelpAttribute
, or Help
for short, that has one positional parameter (string url) and one named argument (string Topic). Positional parameters are defined by the formal parameters for public constructors of the attribute class; named parameters are defined by public read-write properties of the attribute class. The square brackets in the example indicate the use of an attribute in defining the Help
attribute. In this case, the AttributeUsage
attribute indicates that any program element can be decorated with the Help
attribute.
The example
[Help("http://www.mycompany.com/…/Class1.htm")] public class Class1 { [Help("http://www.mycompany.com/…/Class1.htm", Topic ="F")] public void F() {} }
shows several uses of the attribute.
Attribute information for a given program element can be retrieved at run-time by using the NGWS runtime’s reflection support. The example
using System; class Test { static void Main() { Type type = typeof(Class1); object[] arr = type.GetCustomAttributes(typeof(HelpAttribute)); if (arr.Length == 0) Console.WriteLine("Class1 has no Help attribute."); else { HelpAttribute ha = (HelpAttribute) arr[0]; Console.WriteLine("Url = {0}, Topic = {1}", ha.Url, ha.Topic); } } }
checks to see if Class1
has a Help
attribute, and writes out the associated Topic
and Url
values if the attribute is present.