反射手册笔记 5.元数据

1.Attribute,属性(特性),又名元数据,自定义属性。编译期会解释属性,并将对应的标志插入到IL中。
  AOP:面向方面的编程,以声明性的方式控制属性。
  .NET已有的属性类:
    1)Serializable: 仅可用于Class/Struct/Enum/Delegate
    2)NotSerialized:仅用于字段
    3)AssemblyVersion:仅用于程序集,为其定义版本号
    4)Conditional:仅用于方法,用来确定是否忽略方法
    5)WebService:用于class
    6)WebMethod:用于方法
   
  测试标准属性的数据类型:
    System.Reflection.TypeAttribute枚举,用来确定是否为标准类型:Abstract/Class/Interface/Serializable等等共29个。
    枚举不能遍历,要使用逻辑与 & 进行操作:
   
            TypeAttributes attributes  =  objHuman.GetType().Attributes;
            
if  ((attribute  &  TypeAttributes.Serializable)  !=   0 )
            {
                
// atttributes枚举为 Public|Serializable|BeforeFieldInit, 
                
// 与TypeAttributes.Serializable做逻辑与,得到非0值(如果为0说明atttributes中不含Serializable)——是可序列化类型
            }


2.Attribute类语法:
    Attribute类继承于System.Attribute
    .NET中所有属性类均以Attribute结束(定义部分);使用属性时,可以省略结尾的Attribute部分。
    属性类不可以被继承,要声明为sealed。
    属性类必须以<AttributeUsage>开始,从而指定属性可以用于类/方法/结构/...,如:
       <AttributeUsage(AttributeTarget.Class | AttributeTarget.Struct)——表示该属性类可以用于类和结构。
       AttributeTarget.All表示所有类型。
    通过指定AllowMultiple:=false/true来说明属性是否可以在相同的代码元素中多次使用,如:
     // 定义属性类
    [AttributeUsage(AttributeTargets.All, Inherited  =   false , AllowMultiple  =   true )]
    
public   class  AuthorAttribute : Attribute
    { 
    
    }

    
// 使用属性类
    [Author( " Jax.Bao " ), Author( " Fish.Xu " )]
    
public   class  CSharpBook
    { 
    
    }

    将参数传递到属性,有两种参数:
       位置参数:强制性要有,按顺序排列参数。通过传递到属性的构造函数,从而完成类的初始化。
       命令参数:可选参数,在位置参数后面,无顺序,参数名与Attribute类中的属性相对应,使用 =的语法,如:
          [DllImport("User32.dll", CharSet=CharSet.Unicode)]
      
       技巧:可以为属性类定义多个构造函数,从而具有更大灵活性。

3.[Conditional("DEBUG")]:"有条件"方法编译
    在方法前A加上[Conditional("DEBUG")]这个标记,并在Main()中调用A方法。
    在Debug状态下,不会执行A方法;但是方法A会编译到IL中,并在相应A方法的IL中标记为Debug,在Main的IL中不会有调用A的动作。
    在Release状态下,方法A同样会编译到IL中,在相应A方法的IL中也会标记为Debug,于是,在Main的IL中就会有调用A的动作。

    * 使用#if DEBUG...#end if也能达到同样效果,据说比[Conditional("DEBUG")]性能高很多。

4.Assembly属性,全局变量,配合Attribute.GetCustomerAttribute()方法使用,示例如下,
    获取AssemblyInfo.cs中的[assembly: AssemblyTitle("TestStatic")]:
            Attribute attribute  =  Attribute.GetCustomAttribute(Assembly.GetCallingAssembly(),
                                   
typeof (AssemblyTitleAttribute),  false );

            AssemblyTitleAttribute ta 
=  (AssemblyTitleAttribute)attribute;
            Response.WriteLine(ta.Title);
    这里,false表示对不包括超类中的自定义属性.

5.定义新的自定义属性:
    MemberInfo有一个GetCustomAttributes()方法,返回一个自定义属性的数组,同样需要一个bool参数,决定是否对包括超类中的自定义属性,示例如下:
            MemberInfo info;
            Object[] attribs 
=  info.GetCustomAttributes( false );
            
foreach  ( object  attrib  in  attribs)
            {
                
// 遍历attribs自定义属性数组
            }

    本章最后一部分讲的是Remoting技术,从略。   

你可能感兴趣的:(元数据)