C#反射读取类定制特性信息

来源:互联网 发布:python gnureadline 编辑:程序博客网 时间:2024/06/08 14:07

此项目又分为3个小项目:

1.WhatsNewAttributes类库文件:用于定义定制特性类,标示跟新信息

2.myClass类库文件:使用WhatsNew定制特性标记的类

3.Checker控制台应用程序:用反射读取myClass中的公共成员方法,以及定制特性

 

因此:myClass类库需引入WhatsNewAttributes类库编译的DLL文件

         Checker控制台应用程序需引入myClass类库编译的DLL文件^-^,WhatsNewAttributes类库编译的DLL文件

 

WhatsNewAttributes类库文件

[c-sharp] view plaincopy
  1. using System;  
  2.   
  3. namespace WhatsNewAttributes  
  4. {  
  5.     /*  
  6.      * 特性类本身用一个特性System.AttributeUsage来标记,只能用在特性上,不能应用到类上 
  7.      * 该特性主要标示定制特性可应用到哪些类型的程序元素上 
  8.      *   
  9.      * AttributeTargets:指定定制特性可应用到哪些类型的程序元素上,可用"|"指定多个元素 
  10.      * AllowMultiple参数:表示一个特性是否可多次应用到同一项上 
  11.      * Inherited参数:表示应用到类,接口,方法,属性上的特性可自动应用到所有派生类,接口,方法,属性,重写版本上 
  12.      *  
  13.      * 特性类派生于System.Attribute类 
  14.      */  
  15.   
  16.     /***************** 定义特性类LastModifiedAttribute ******************/  
  17.     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple=true, Inherited=false)]  
  18.     public class LastModifiedAttribute : Attribute  
  19.     {  
  20.         private DateTime _dateModified;  
  21.         private string _changes;  
  22.         private string _issues;  
  23.   
  24.         //特性类构造函数  
  25.         public LastModifiedAttribute(string dateModified, string changes)  
  26.         {  
  27.             this._dateModified = DateTime.Parse(dateModified);  
  28.             this._changes = changes;  
  29.         }  
  30.   
  31.         public DateTime DateModified  
  32.         {  
  33.             get { return _dateModified; }  
  34.         }  
  35.   
  36.         public string Changes  
  37.         {  
  38.             get { return _changes; }  
  39.         }  
  40.   
  41.         //特性类可选属性  
  42.         public string Issues  
  43.         {  
  44.             get { return _issues; }  
  45.             set { _issues = value; }  
  46.         }  
  47.     }  
  48.   
  49.     /***************** 定义特性类SupportsWhatsNewAttribute,指示该特性仅用于程序集 ******************/  
  50.     [AttributeUsage(AttributeTargets.Assembly)]  
  51.     public class SupportsWhatsNewAttribute : Attribute  
  52.     {  
  53.     }  
  54. }  

 

myClass类库文件

[c-sharp] view plaincopy
  1. using System;  
  2. //添加创建特性类生成的引用,包含其命名空间,这样编译器才能识别这些特性  
  3. using WhatsNewAttributes;  
  4.   
  5. //用SupportsWhatsNes特性标记程序集本身  
  6. [assembly : SupportsWhatsNew]  
  7. namespace myClass  
  8. {  
  9.     //在类上使用定制特性  
  10.     [LastModified("14 Feb 2008""改良了XX功能1")]  
  11.     [LastModified("16 Jun 2010""改良了XX功能2")]  
  12.     public class myClass  
  13.     {  
  14.         private string _my;  
  15.   
  16.         public string My  
  17.         {  
  18.             get { return _my; }  
  19.             set { _my = value; }  
  20.         }  
  21.   
  22.         //在方法上使用定制特性,添加可选属性Issues  
  23.         [LastModified("17 Jun 2010""改良:从写了基类的ToString()方法", Issues="这是个突出问题")]  
  24.         public override string ToString()  
  25.         {  
  26.             return "新更新的重写方法";  
  27.         }  
  28.   
  29.         //私有方法  
  30.         private void myFun()  
  31.         { }  
  32.     }  
  33. }  

 

Checker控制台应用程序

[c-sharp] view plaincopy
  1. using System;  
  2. using System.Reflection;  
  3. //添加创建特性类生成的引用,包含其命名空间,这样编译器才能识别这些特性  
  4. using WhatsNewAttributes;  
  5.   
  6. namespace Checker  
  7. {  
  8.     class Checker  
  9.     {  
  10.         static void Main(string[] args)  
  11.         {  
  12.             /* Assembly类:在System.Reflection命名空间定义,允许访问给定程序集的元数据 
  13.              *   1.使用Assembly实例前,需要加入相应程序集 
  14.              *     Assembly.Load():参数为程序集名称 
  15.              *     Assembly.LoadFrom():参数为程序集的完整路径名 
  16.              *   2.查找在程序集中定义的类型Assembly.GetTypes() 
  17.              *   3.查找程序集的定制特性Attribute.GetCustomAttributes(assemblyObj) 
  18.              *     定义定制特性时,必须为他们编写类,定制特性与对象一样,加载了程序集后 
  19.              *     就可以读取这些特定对象,查看他们的属性,调用他们的方法 
  20.              *     a.所有特性都作为一般Attribute引用来获取 
  21.              *     b.如要调用为定制特性定义的方法属性,就要把这些引用显示转化为相关定制特性类 
  22.              */   
  23.             Assembly theAssembly = Assembly.Load("myClass");  
  24.             Attribute supportsAttribute = Attribute.GetCustomAttribute(theAssembly,typeof(SupportsWhatsNewAttribute));  
  25.   
  26.             string Name = theAssembly.FullName;  
  27.   
  28.             if (supportsAttribute == null)  
  29.             {  
  30.                 Console.WriteLine("此程序集不支持SupportsWhatsNew特性");  
  31.                 return;  
  32.             }  
  33.             else  
  34.             {  
  35.                 Console.WriteLine("程序集:" + Name);  
  36.             }  
  37.   
  38.             //Assembly类的特性可以获得在相应程序集中定义的所有类型的信息  
  39.             //调用GetTypes()方法,获得此程序集中定义的类型数组,此处只定义了一个myClass类  
  40.             Type[] types = theAssembly.GetTypes();  
  41.       //注:此处如果只要同一项目下的某类的类型,可以直接使用typeof(ClassName)来代替
  42.             Console.WriteLine("信息总数:" + types.Length);         //1  
  43.   
  44.             foreach (Type definedType in types)  
  45.             {  
  46.                 //如果该definedType不是一个类  
  47.                 if (!(definedType.IsClass))  
  48.                 {  
  49.                     //退出程序  
  50.                     return;  
  51.                 }  
  52.                 else  
  53.                 {  
  54.                     Console.WriteLine("成员名:" + definedType.Name);          //myClass  
  55.                 }  
  56.   
  57.                 //检索myClass类的自定义属性数组  
  58.                 Attribute[] attribs = Attribute.GetCustomAttributes(definedType);  
  59.   
  60.                 if (attribs.Length == 0)  
  61.                 {  
  62.                     Console.WriteLine("这个类没有改良过");  
  63.                 }  
  64.                 else  
  65.                 {  
  66.                     foreach (Attribute attrib in attribs)  
  67.                     {  
  68.                         WriteAttributeInfo(attrib);  
  69.                     }  
  70.                 }  
  71.   
  72.                 //检索myClass类的所有公共方法数组  
  73.                 MemberInfo[] methods = definedType.GetMethods();  
  74.                 Console.WriteLine("修改过的方法:");  
  75.   
  76.                 foreach (MethodInfo nextMethod in methods)  
  77.                 {  
  78.                     //检索myClass类的当前公共方法的由LastModifiedAttribute标示的定制属性数组  
  79.                     object[] attribs2 = nextMethod.GetCustomAttributes(typeof(LastModifiedAttribute), false);  
  80.   
  81.                     if (attribs2 != null)  
  82.                     {  
  83.                         Console.WriteLine( nextMethod.ReturnType + " " + nextMethod.Name + "()");  
  84.   
  85.                         foreach(Attribute nextAttrib in attribs2)  
  86.                         {  
  87.                             WriteAttributeInfo(nextAttrib);  
  88.                         }  
  89.                     }  
  90.                 }  
  91.             }  
  92.   
  93.             Console.ReadLine();  
  94.         }  
  95.   
  96.         //显示该自定义属性的信息  
  97.         public static void WriteAttributeInfo(Attribute attrib)  
  98.         {  
  99.             //定义特性类LastModifiedAttribute就是为了方便实例化后访问类中个属性  
  100.             LastModifiedAttribute lastModifiedAttrib = attrib as LastModifiedAttribute;  
  101.   
  102.             if (lastModifiedAttrib == null)  
  103.             {  
  104.                 return;  
  105.             }  
  106.   
  107.             DateTime modifiedDate = lastModifiedAttrib.DateModified;  
  108.   
  109.             Console.WriteLine("改良:" + modifiedDate.ToLongDateString() + "," + lastModifiedAttrib.Changes);  
  110.   
  111.             if (lastModifiedAttrib.Issues != null)  
  112.             {  
  113.                 Console.WriteLine("突出问题:" + lastModifiedAttrib.Issues);  
  114.             }  
  115.         }  
  116.     }  
  117. }