【C#语言规范版本5.0学习】1.11 特性
C# 程序中的类型、成员和其他实体都支持修饰符,这些修饰符控制它们的行为的某些方面。
例如,方法的可访问性是使用 public、protected、internal 和 private 修饰符来控制的。
C# 使此功能一般化,以便能够将用户定义类型的声明信息附加到程序实体,并在运行时检索。这种附加的声明信息是程序通过定义和使用特性 (attribute) 来指定的。
下面的示例声明一个 HelpAttribute 特性,该特性可放置在程序实体上,以便提供指向其关联文档的链接。
using System; public class HelpAttribute: Attribute { string url; string topic; public HelpAttribute(string url) { this.url = url; } public string Url { get { return url; } } public string Topic { get { return topic; } set { topic = value; } } }
所有特性类都从 .NET Framework 提供的 System.Attribute 基类派生而来。可以通过在相关声明之前紧邻的方括号内提供特性名和任何实参来应用特性。如果特性的名称以 Attribute 结尾,在引用该特性时可以省略此名称后缀。例如,HelpAttribute 特性可以按如下方式使用。
[Help("http://msdn.microsoft.com/.../MyClass.htm")] public class Widget { [Help("http://msdn.microsoft.com/.../MyClass.htm", Topic = "Display")] public void Display(string text) {} }
此示例将一个 HelpAttribute 附加到 Widget 类,并且将另一个 HelpAttribute 附加到该类中的 Display 方法。特性类的公共构造函数控制在将特性附加到程序实体时,必须提供的信息。可以通过引用特性类的公共读写属性提供附加信息,例如前面对 Topic 属性的引用。
下面的示例演示如何使用反射在运行时检索给定程序实体的特性信息。
using System; using System.Reflection; class Test { static void ShowHelp(MemberInfo member) { HelpAttribute a = Attribute.GetCustomAttribute(member,typeof(HelpAttribute)) as HelpAttribute; if (a == null) { Console.WriteLine("No help for {0}", member); } else { Console.WriteLine("Help for {0}:", member); Console.WriteLine(" Url={0}, Topic={1}", a.Url, a.Topic); } } static void Main() { ShowHelp(typeof(Widget)); ShowHelp(typeof(Widget).GetMethod("Display")); } }
当通过反射请求特定特性时,将使用程序源中提供的信息调用特性类的构造函数,并返回生成的特性实例。如果通过属性提供了附加信息,那些属性将在返回特性实例之前被设置为给定的值。