反射手册笔记 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个。
枚举不能遍历,要使用逻辑与 & 进行操作:
2.Attribute类语法:
Attribute类继承于System.Attribute
.NET中所有属性类均以Attribute结束(定义部分);使用属性时,可以省略结尾的Attribute部分。
属性类不可以被继承,要声明为sealed。
属性类必须以<AttributeUsage>开始,从而指定属性可以用于类/方法/结构/...,如:
<AttributeUsage(AttributeTarget.Class | AttributeTarget.Struct)——表示该属性类可以用于类和结构。
AttributeTarget.All表示所有类型。
通过指定AllowMultiple:=false/true来说明属性是否可以在相同的代码元素中多次使用,如:
将参数传递到属性,有两种参数:
位置参数:强制性要有,按顺序排列参数。通过传递到属性的构造函数,从而完成类的初始化。
命令参数:可选参数,在位置参数后面,无顺序,参数名与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")]:
5.定义新的自定义属性:
MemberInfo有一个GetCustomAttributes()方法,返回一个自定义属性的数组,同样需要一个bool参数,决定是否对包括超类中的自定义属性,示例如下:
本章最后一部分讲的是Remoting技术,从略。
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)——是可序列化类型
}
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
{
}
[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表示对不包括超类中的自定义属性.typeof(AssemblyTitleAttribute), false);
AssemblyTitleAttribute ta = (AssemblyTitleAttribute)attribute;
Response.WriteLine(ta.Title);
5.定义新的自定义属性:
MemberInfo有一个GetCustomAttributes()方法,返回一个自定义属性的数组,同样需要一个bool参数,决定是否对包括超类中的自定义属性,示例如下:
MemberInfo info;
Object[] attribs = info.GetCustomAttributes(false);
foreach (object attrib in attribs)
{
//遍历attribs自定义属性数组
}
Object[] attribs = info.GetCustomAttributes(false);
foreach (object attrib in attribs)
{
//遍历attribs自定义属性数组
}
本章最后一部分讲的是Remoting技术,从略。