目录:
1 What特性是什么
2 Why特性有什么用(为什么使用特性)
3 HOW怎样使用特性
4 检索存储在属性中的信息
1 What 特性是什么:
特性概述
特性是提供有关编程元素(如类型、字段、方法和属性)的附加信息的描述性标记。其他应用程序(如 Visual Basic 编译器)可以引
用特性中的其他信息以确定如何使用这些项。
特性和元数据
特性与 Visual Basic .NET 程序集的“元数据”一起保存。元数据是描述由运行库托管的每个元素的信息。这可以包括调试和垃圾回
收所需的信息,也包括安全特性、封送处理数据、扩展类和成员定义、版本绑定以及运行时需要的其他任何信息。
使用特性指定元数据的方法与使用 Public 和 Private 之类的关键字来提供有关访问级别的信息的方法很相似。但是,与关键字不同
,大多数特性不特定于具体语言。使用特性可以在不要求对编译器进行更改的情况下扩展 Visual Basic 语言的功能。
特性的功能与性能
有关特性的一些要点包括:
可以将一个或多个特性应用到整个程序集、模块或较小的程序元素(如类和属性)。
特性可以与方法和属性相同的方式接受参数。
特性分为两组:.NET Framework 和 Visual Basic .NET 使用的特性和只对特定应用程序有意义的自定义特性。
虽然 .NET Framework 包含许多有用的特性,但如果有必要,可以定义自己的自定义特性。
自定义特性在基于 System.Attribute 类的特性类中定义。特性类自身使用 AttributeUsage 来提供有关可以如何使用特性的附加信息
。
从特性中检索元数据的过程被称为“反射”。反射涉及使用工具允许对象检索和检查有关它们自己的成员的元数据。
特性参数:
可选参数,必选参数,定位参数,命名参数
定位参数:按其在特性的构造函数声明的顺序指定的参数
<customAttr(True,False)>传递给特性类中的sub new的参数
命名参数:直接设置属性和字段的值,通过缎带参数名称追加":="可指定命名参数
<CustomAttr(Update:=true,Keep:=False)>
2.特性有什么用
特性的常见用途
在使用公共语言运行库和类库时,有时可能需要使用特性。以下列表包含特性的几个常见用途:
在 XML Web services 中,使用 WebMethod 特性标记方法,以指示该方法应可通过 SOAP 协议进行调用。有关更多信息,请参见
WebMethodAttribute 类。
描述当与本机代码进行交互操作时如何封送方法参数。有关更多信息,请参见 MarshalAsAttribute 类。
描述类、方法和接口的 COM 属性。
将组件标记为 COM,以便 Visual Basic 编译器生成创建 COM 组件所需的附加代码。有关更多信息,请参见 ComClassAttribute 类。
使用 DllImportAttribute 类调用非托管代码。
在标题、版本、说明或商标方面描述您的程序集。
描述要持久性序列化类的哪些成员。
描述如何映射类成员和 XML 节点以便进行 XML 序列化。
描述方法的安全要求。
指定用于强制安全性的特性。
由实时 (JIT) 编译器控制优化,以便易于调试代码。
可以采用多种其他方式使用特性,还可以创建自定义特性。
3 HOW怎样使用特性
通过向程序元素(属性,方法,事件,类和程序集)添加特性块来应用应用特性。
特性块由尖括号组成,其中包含逗号分隔的特性声明列表。
特性声明由可选特性修饰符(如Module,Assembly),特性名称,所需的定位参数列表,和可选命名参数列表组成。
必须将带有修饰符特性放在源文件顶部的特性部分中。
以下代码设置为程序集定义标题的程序集特性和指示模块符合“公共语言规范”的模块特性:
Option Explicit On
Imports System.Reflection
<Assembly:AssemblyTitleAttribute("production assembly 4"),Moudle:ClsCompliant(True)>
Namespace MyNameSpace
....
end Namespace
也可通过AssemblyInfo.VB文件应用程序集特性。
当应用于诸如属性的程序元素时,特性优先于元素
<CustomAttr(Update:=true)>Class Class1
根据约定,所有特性名称都以单词"Attribute"结束,以便将他们与".net Framework"中的其他项区分,但使用特性时不需要指定特
性后缀。
EXP
下面的示例定义只能应用于类的自定义特性:
'****************************************************************************************************
<AttributeUsage(AttributeTargets.Class)> Public Class CustomAttribute
Inherits System.Attribute
'Declare two private fields to store the property values.
Private m_Label As String
Private m_Value As Integer
'The Sub New constructor is the only way to set the properties.
Public Sub New(ByVal _Label As String, ByVal _Value As Integer)
m_Label = _Label
m_Value = _Value
End Sub
Public Overridable ReadOnly Property Label() As String
Get
Return m_Label
End Get
End Property
Public Overridable ReadOnly Property Value() As Integer
Get
Return m_Value
End Get
End Property
End Class
只有特性类的构造函数可以设置在此特性中定义的属性。下面的代码展示可以如何使用该特性:
' Apply the custom attribute to this class.
<Custom("Some metadata", 66)> Class ThisClass
' Add class members here.
End Class
'****************************************************************************************************
4 检索存储在属性中的信息
首先声明检索的属性实例
然后使用attribute.GetCustomAttribute方法将新属性初始化为要检索的属性值.
初始化新属性后,只需要使用其属性值获取值即可
检索应用于指定程序集或从基类继承的指定类型的自定义属性。
Overloads Public Shared Function GetCustomAttribute(Assembly, Type) As Attribute
检索应用于类的指定成员或从基类继承的指定类型的自定义属性。
Overloads Public Shared Function GetCustomAttribute(MemberInfo, Type) As Attribute
检索应用于指定模块或从基类继承的指定类型的自定义属性。
Overloads Public Shared Function GetCustomAttribute(Module, Type) As Attribute
检索应用于类成员的指定参数或从基类继承的指定类型的自定义属性。
Overloads Public Shared Function GetCustomAttribute(ParameterInfo, Type) As Attribute
检索应用于指定程序集或从基类继承(可选)的指定类型的自定义属性。
Overloads Public Shared Function GetCustomAttribute(Assembly, Type, Boolean) As Attribute
检索应用于类的指定成员或从基类继承(可选)的指定类型的自定义属性。
Overloads Public Shared Function GetCustomAttribute(MemberInfo, Type, Boolean) As Attribute
检索应用于指定模块或从基类继承(可选)的指定类型的自定义属性。
Overloads Public Shared Function GetCustomAttribute(Module, Type, Boolean) As Attribute
检索应用于类成员的指定参数或从基类继承(可选)的指定类型的自定义属性。
Overloads Public Shared Function GetCustomAttribute(ParameterInfo, Type, Boolean) As Attribute
EXP
'****************************************************************************************************
[Visual Basic]
<AttributeUsage(AttributeTargets.All)> Public Class DeveloperAttribute
Inherits System.Attribute
Private m_name As String
Private m_level As String
Private m_reviewed As Boolean
Public Sub New(name As String, level As String)
Me.m_name = name
Me.m_level = level
Me.m_reviewed = False
End Sub
Public Overridable ReadOnly Property Name() As String
Get
Return m_name
End Get
End Property
Public Overridable ReadOnly Property Level() As String
Get
Return m_level
End Get
End Property
Public Overridable Property Reviewed() As Boolean
Get
Return m_reviewed
End Get
Set
m_reviewed = value
End Set
End Property
End Class
'***************************************************************************************************
Imports System
<Developer("Joan Smith", "42", Reviewed := True)> Class MainApp
Public Shared Sub Main()
GetAttribute(GetType(MainApp))
End Sub
Public Shared Sub GetAttribute(t As Type)
Dim MyAttribute As DeveloperAttribute = _
CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)
'注意前一句的语句使用方法
'1 调用GetAttribute函数时已经将MainApp类返回type,传递过来了
'2 gettype(DeveloperAttribute)应该是返回一个type类型 ,即DeveloperAttribute的类对象
'3 通过attribute.GetCustomAttribute(t,GetType(DeveloperAttribute))返回mainAPP类中的属性对象
'4 将获得的属性对象通过ctype转换成DeveloperAttribute类型,并初始化实例
'
If MyAttribute Is Nothing Then
Console.WriteLine("The attribute was not found.")
Else
Console.WriteLine("The Name Attribute is: {0}.", MyAttribute.Name)
Console.WriteLine("The Level Attribute is: {0}.", MyAttribute.Level)
Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute.Reviewed)
End If
End Sub
End Class
'***************************************************************************************************
注1: 在前一示例中用到的gettype
GetType运算符
返回指定类型的type对象,type对象可以用于检索关于类型的信息,如类型的属性,方法和事件.
gettype(typename)
注2: 对type类的查询结果为:
Type 为 System.Reflection 功能的根,也是访问元数据的主要方式。
使用 Type 的成员获取关于类型声明的信息,
如构造函数、方法、字段、属性和类的事件,以及在其中部署该类的模块和程序集。
如果没有 ReflectionPermission,代码只能访问已加载程序集的公共成员。
这包括但不限于对 Object.GetType 的不受限制的访问、通过 Type.GetType 对公共导出类型的访问以及对 GetTypeFromHandle
的访问。
Type 的某些属性(例如 FullName 和 Attributes)可以在没有 ReflectionPermission 的情况下访问。
Type 是允许多个实现的抽象基类。
系统将总是提供派生类 RuntimeType。
在反射中,所有以 Runtime 一词开头的类对系统中的每个对象都只能创建一次,并且这些类支持比较操作。
***********************************
对ReflectionPerMission类的查询结果为:
System.Object
System.Security.CodeAccessPermission
System.Security.Permissions.ReflectionPermission
<Serializable>
NotInheritable Public Class ReflectionPermission
Inherits CodeAccessPermission
Implements IUnrestrictedPermission
通过systemReflection API控制对元数据的访问
************************************
system.type类对于反射起着核心的作用.
当反射请求加载的类型时,公共语言运行库将为它创建一个type
你可以使用type对象的方法,字段,属性和嵌套来查找有关该类型的所有信息
使用assembly.gettype或assembly.gettypes时传入所需要类型的名称,可从尚未加载的程序集中获取type对象
使用type.gettype可从已加载的程序集中获取type对象
使用module.gettype和module.gettypes可获取模块type对象
type类的签名如下:
System.Object
System.Reflection.MemberInfo
System.Type
System.Reflection.Emit.EnumBuilder
System.Reflection.Emit.TypeBuilder
System.Reflection.TypeDelegator
<Serializable>
<ClassInterface(ClassInterfaceType.AutoDual)>
MustInherit Public Class Type
Inherits MemberInfo
Implements IReflect