在Visual C#中定义和使用自己的特性 |
来源:ChinaItLab 作者:佚名 时间:2007-8-30 |
|
一些读者可能会感到惊奇,因为对于源代码修改的信息可以通过使用注释这种传统的做法。.net已经使用工具,通过在注释里使用XML块,把这些信息很好的组织起来。
在源代码对应的位置,你可以很容易的看到你的注释。你可以通过文本,分析源代码里的注释,从而处理这些信息,但是这个过程是单调冗长的,并且很容易出现错误。.NET提供了工具来处理注释里的XML块,这样可以消除此类问题。
使用自定义特性可以使你达到同样的效果,它同样提供了一种可以有效组织的方法,用于记录和处理这些信息,并且它还有一个额外的优势。考虑如下情况,当把源代码编译成二进制代码的时候,你是否已经丢失了代码的注释?毫无疑问,注释已经作为副产品,永远的从可执行代码里移出。相比之下,特性的值已经变成了元数据的一部分,永远的绑定到一个程序集里。在没有源代码的情况下,你依然可以访问这些注释信息。
另外,在源代码里允许特性构造一个与当初在设计时值一样的实例。
获取自定义特性的值
到此,尽管你已经在类和方法上应用了自定义属性,但在实战中你还没有真正的看到它。不管你是否附加了特性,看起来好像什么事情也没有发生。但事实上,事情已经发生了变化,你完全不用理会我的话,你可以用MSIL反编译工具,打开一个包含使用了自定义特性类型的EXE或者DLL文件。MSIL反编译工具能使你看到在IL代码里你定义的特性和它的值。图一是使用ILDASM工具,打开本文中例子编译的EXE文件所看到的。
尽管通过反编译程序集,看到了特性的值,证明了它们的确存在,但是你仍然没有看到跟它们相关的行为。那么现在,你就可以使用反射API遍历一个程序集包含的类型,查询你自定义的特性,在应用了特性的类型上获取特性的值。
考虑如下测试代码的一般的做法。程序加载指定的程序集,得到一个包含程序集中所有成员的数组,在它们中间,迭代寻找应用了[DefectTrack]特性的类。对于应用了[DefectTrack]特性的类,测试程序将在控制台上输出特性的值。对于类型中的方法,程序仍然采用了同样的步骤和迭代。这些循环采用它们的方式在整个程序集里“游走”。
using System ; using System.Reflection ; using MyAttributeClasses ;
public class TestMyAttribute { public static void Main( ) { DisplayDefectTrack( "MyAttributes" ) ; Console.ReadLine(); }
public static void DisplayDefectTrack( string lcAssembly ) { Assembly loAssembly = Assembly.Load( lcAssembly ) ;
Type[ ] laTypes = loAssembly.GetTypes( ) ;
foreach( Type loType in laTypes ) { Console.WriteLine("*======================*" ) ; Console.WriteLine( "TYPE:\t" + loType.ToString( ) ) ; Console.WriteLine( "*=====================*" ) ;
object[ ] laAttributes = loType.GetCustomAttributes( typeof( DefectTrackAttribute ), false ) ;
if( laAttributes.Length > 0 ) Console.WriteLine( "\nMod/Fix Log:" ) ;
foreach( Attribute loAtt in laAttributes ) { DefectTrackAttribute loDefectTrack = (DefectTrackAttribute)loAtt ;
Console.WriteLine( "----------------------" ) ; Console.WriteLine( "Defect ID:\t" + loDefectTrack.DefectID ) ; Console.WriteLine( "Date:\t\t" + loDefectTrack.ModificationDate ) ; Console.WriteLine( "Developer ID:\t" + loDefectTrack.DeveloperID ) ; Console.WriteLine( "Origin:\t\t" + loDefectTrack.Origin ) ; Console.WriteLine( "Comment:\n" + loDefectTrack.FixComment ) ; }
MethodInfo[ ] laMethods = loType.GetMethods( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly ) ;
if( laMethods.Length > 0 ) { Console.WriteLine( "\nMethods: " ) ; Console.WriteLine( "----------------------" ) ; }
foreach( MethodInfo loMethod in laMethods ) { Console.WriteLine( "\n\t" + loMethod.ToString( ) ) ;
object[ ] laMethodAttributes = loMethod.GetCustomAttributes( typeof( DefectTrackAttribute ), false ) ;
if( laMethodAttributes.Length > 0 ) Console.WriteLine( "\n\t\tMod/Fix Log:" ) ;
foreach( Attribute loAtt in laMethodAttributes ) { DefectTrackAttribute loDefectTrack = (DefectTrackAttribute)loAtt ; Console.WriteLine( "\t\t----------------" ) ; Console.WriteLine( "\t\tDefect ID:\t" + loDefectTrack.DefectID ) ; Console.WriteLine( "\t\tDeveloper ID:\t" + loDefectTrack.DeveloperID ) ; Console.WriteLine( "\t\tOrigin:\t\t" + loDefectTrack.Origin ) ; Console.WriteLine( "\t\tComment:\n\t\t" + loDefectTrack.FixComment ) ; } } Console.WriteLine( "\n\n" ) ; } } } |
上一页 [1] [2] [3] [4] [5] 下一页
 【责编:Youping】 |
 |
|
|
|