1: [Obsolete("I''m so old, don''t kill me!", true)]
2: public virtual void Run(int speed)
3: {
4: // Running is good for health.
5: }
上面大致介绍了一下特性的使用与作用,接下来我们要向大家展示的是如何通过自定义特性来提高程序的灵活性,如果特性机制仅仅能使用.NET提供的那几种特性,不就太不过瘾了么。
首先,特性也是类。不同于其它类的是,特性都必须继承自System.Attribute类,否则编译器如何知道谁是特性谁是普通类呢。当编译器检测到一个类是特性的时候,它会识别出其中的信息并存放在元数据当中,仅此而已,编译器并不关心特性说了些什么,特性也不会对编译器起到任何作用,正如航空公司并不关心每个箱子要去哪里,只有箱子的主人和搬运工才会去关心这些细节。假设我们现在就是航空公司的管理人员,需要设计出前面提到的登机牌,那么很简单,我们先看看最主要的信息有哪些:
1: public class BoardingCheckAttribute : Attribute
2: {
3: public string ID { get; private set; }
4: public string Name { get; private set; }
5: public int FlightNumber { get; private set; }
6: public int PostionNumber { get; private set; }
7: public string Departure { get; private set; }
8: public string Destination { get; private set; }
9: }
我们简单列举这些属性作为航空公司登机牌上的信息,用法和前面的一样,贴到HumanBase上就行了,说明此人具备登机资格。这里要简单提一下,你可能已经注意到了,在使用BoardingCheckAttribute的时候已经把Attribute省略掉了,不用担心,这样做是对的,因为编译器默认会自己加上然后查找这个属性类的。哦,等一下,我突然想起来他该登哪架飞机呢?显然,在这种需求下,我们的特性还没有起到应有的作用,我们还的做点儿工作,否则乘客面对一张空白的机票一定会很迷茫。
于是,我们必须给这个特性加上构造函数,因为它不仅仅表示登机的资格,还必须包含一些必要的信息才行:
1: public BoardingCheckAttribute(string id, string name, string flightNumber, string positionNumber, string departure, string destination)
2: {
3: this.ID = id;
4: this.Name = name;
5: this.FlightNumber = flightNumber;
6: this.PositionNumber = positionNumber;
7: this.Departure = departure;
8: this.Destination = destination;
9: }
OK,我们的乘客就可以拿到一张正式的登机牌登机了,have a good flight!
1: static void Main(string args)
2: {
3: BoardingCheckAttribute boardingCheck = null;
4: object customAttributes = typeof(HumanPropertyBase).GetCustomAttributes(true);
5:
6: foreach (var attribute in customAttributes)
7: {
8: if (attribute is BoardingCheckAttribute)
9: {
10: boardingCheck = attribute as BoardingCheckAttribute;
11:
12: Console.WriteLine(boardingCheck.Name
13: + "''s ID is "
14: + boardingCheck.ID
15: + ", he/she wants to "
16: + boardingCheck.Destination
17: + " from "
18: + boardingCheck.Departure
19: + " by the