分享
 
 
 

在.NET运行时了解类型信息(3)

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

访问自定义属性

当属性与程序元素相关联后,可以使用反射来查询它们是否存在以及它们的值。用于查询属性的主要反射方法包含在 System.Reflection.MemberInfo.GetCustomAttributes 和 System.Reflection.Assembly.GetCustomAttributes 中。

自定义属性的可访问性根据附加该属性的程序集来进行检查。这相当于检查附加自定义属性的程序集中的类型上的方法是否可以调用自定义属性的构造函数。

诸如 System.Reflection.Assembly.GetCustomAttributes(Type, Boolean) 等方法检查类型参数的可见性和可访问性。只有包含用户定义类型的程序集中的代码才能使用 GetCustomAttributes 检索该类型的自定义属性。

以下代码示例是典型的自定义属性设计模式。它说明运行库自定义属性反射模型。

[C#]

System.DLL

public class DescriptionAttribute : Attribute

{

}

System.Web.DLL

internal class MyDescriptionAttribute : DescriptionAttribute

{

}

public class LocalizationExtenderProvider

{

[MyDescriptionAttribute(...)]

public CultureInfo GetLanguage(...)

{

}

}

如果试图为附加到 GetLanguage 方法的公共自定义属性类型 DescriptionAttribute 检索自定义属性,运行库将执行以下操作:

运行库检查 Type.GetCustomAttributes(Type type) 的 DescriptionAttribute 类型参数是否为公共的,并检查其是否可见或可以访问。

运行库检查从 DescriptionAttribute 导出的用户定义类型 MyDescriptionAttribute 在 System.Web.DLL 程序集(它在该程序集中附加到 GetLanguage() 方法)内是否可见和可以访问。

运行库检查 MyDescriptionAttribute 的构造函数是否在 System.Web.DLL 程序集中可见和可以访问。

运行库调用带有自定义属性参数的 MyDescriptionAttribute 的构造函数,然后将新对象返回给调用方。

自定义属性反射模型可能会在定义类型的程序集外泄漏用户定义类型的实例。这与运行库系统库中返回用户定义类型的实例的成员(例如返回 RuntimeMethodInfo 对象数组的 Type.GetMethods())相同。为了防止客户端发现关于用户定义的自定义属性类型的信息,请将该类型的成员定义为非公共成员。

以下代码示例说明使用反射访问自定义属性的基本方法。

[C#]

class MainClass

{

public static void Main()

{

System.Reflection.MemberInfo info = typeof(MyClass);

object[] attributes = info.GetCustomAttributes();

for (int i = 0; i < attributes.Length; i ++)

{

System.Console.WriteLine(attributes[i]);

}

}

}

指定完全限定的类型名称

要为各种反射操作提供有效的输入,必须指定类型名称。完全限定的类型名称包含程序集名称指定、命名空间指定和类型名称。类型名称指定将由 Type.GetType、Module.GetType、ModuleBuilder.GetType 和 Assembly.GetType 来使用。

类型名称的 Backus-Naur 形式语法

Backus-Naur 形式 (BNF) 定义正式语言的语法。下表中的 BNF 词法规则将说明如何识别有效的输入。最终元素(无法再减小的元素)将全部以大写字母显示。非最终元素(可以再减小的元素)则显示为大小写混合或带单引号的字符串,但单引号 (') 不是语法本身的一部分。管道字符 (|) 表示具有子规则的规则。

完全限定类型名称的 BNF 语法

TypeSpec := ReferenceTypeSpec

| SimpleTypeSpec

ReferenceTypeSpec := SimpleTypeSpec '&'

SimpleTypeSpec := PointerTypeSpec

| ArrayTypeSpec

| TypeName

PointerTypeSpec := SimpleTypeSpec '*'

ArrayTypeSpec := SimpleTypeSpec '[ReflectionDimension]'

| SimpleTypeSpec '[ReflectionEmitDimension]'

ReflectionDimension := '*'

| ReflectionDimension ',' ReflectionDimension

| NOTOKEN

ReflectionEmitDimension := '*'

| Number '..' Number

| Number '...'

| ReflectionDimension ',' ReflectionDimension

| NOTOKEN

Number := [0-9]+

TypeName := NamespaceTypeName

| NamespaceTypeName ',' AssemblyNameSpec

NamespaceTypeName := NestedTypeName

| NamespaceSpec '.'NestedTypeName

NestedTypeName := IDENTIFIER

| NestedTypeName '+' IDENTIFIER

NamespaceSpec := IDENTIFIER

| NamespaceSpec '.'IDENTIFIER

AssemblyNameSpec := IDENTIFIER

| IDENTIFIER ',' AssemblyProperties

AssemblyProperties := AssemblyProperty

| AssemblyProperties ',' AssemblyProperty

AssemblyProperty := AssemblyPropertyName '=' AssemblyPropertyValue

指定特殊字符

在 TypeName 中,IDENTIFIER 是由语言规则所确定的任何有效名称。

反斜杠 (\) 可用作转义符来分隔以下用作 IDENTIFIER 一部分的标记。

标记

含义

\,

程序集分隔符。

\+

嵌套类型分隔符。

\&

引用类型。

\*

指针类型。

\[

数组维度分隔符。

\]

数组维度分隔符。

\.

只有在数组指定中使用句点时,才应在句点前使用反斜杠。NamespaceSpec 中的句点不采用反斜杠。

用作字符串的反斜杠。

请注意,在除 AssemblyNameSpec 之外的所有 TypeSpec 组成部分中,空格都是相关的。在 AssemblyNameSpec 中,“,”分隔符之前的空格相关,但“,”分隔符之后的空格将被忽略。

反射类(如 Type.FullName)将返回经过处理的名称,以便使返回的名称可以在对 GetType 的调用中使用(例如在 MyType.GetType(myType.FullName) 中)。

例如,某个类型的完全限定名称可能是 Ozzy.OutBack.Kangaroo+Wallaby,MyAssembly。

如果命名空间为 Ozzy.Out+Back,则必须在加号前加反斜杠。否则,分析器会将其解释为嵌套分隔符。反射会将该字符串当作 Ozzy.Out\+Back.Kangaroo+Wallaby,MyAssembly 发出。

指定程序集名称

程序集名称指定中所需的最少信息为程序集的文本名称 (IDENTIFIER)。您可以在 IDENTIFIER 后添加下表所述的逗号分隔属性/值对列表。IDENTIFIER 命名应遵循文件命名的规则。IDENTIFIER 不区分大小写。

有效的程序集属性

属性名称

说明

允许值

Version

程序集版本号

Major.Minor.Build.Revision,其中 Major、Minor、Build 和 Revision 是 0 和 65535 之间(含 0 和 65535)的整数。

PublicKey

完全公钥

完全公钥的十六进制字符串值。指定 null(在 Microsoft Visual Basic .NET 中为 Nothing)可显式地指示私有程序集。

PublicKeyToken

公钥标记(完全公钥的 8 字节哈希)

公钥标记的十六进制字符串值。指定 null(在 Visual Basic .NET 中为 Nothing)可显式地指示私有程序集。

Culture

程序集区域性

程序集的 RFC-1766 格式区域性,或者对于独立于语言(非附属)的程序集为“非特定”。

Custom

自定义的二进制大对象 (BLOB)。它当前仅用于由本机图像生成器 (Ngen.exe) 生成的程序集。

自定义的字符串,由本机图像生成器工具用来向程序集缓存通知所安装的程序集为本机图像,因此将安装在本机图像缓存中。也称作 Zap 字符串。

以下代码示例显示带有默认区域性且名称简单的程序集的 AssemblyName。

[C#]

com.microsoft.crypto, Culture=""

以下代码示例显示区域性为“en”且带有强名称的程序集的完全限定引用。

[C#]

com.microsoft.crypto, Culture=en, PublicKeyToken=a5d015c7d5a0b012,

Version=1.0.0.0

以下代码示例显示部分指定的 AssemblyName,它可以由带有强名称或简单名称的程序集来满足。

[C#]

com.microsoft.crypto

com.microsoft.crypto, Culture=""

com.microsoft.crypto, Culture=en

以下每个代码示例都显示一个部分指定的 AssemblyName,它必须由带有简单名称的程序集来满足。

[C#]

com.microsoft.crypto, Culture="", PublicKeyToken=null

com.microsoft.crypto, Culture=en, PublicKeyToken=null

以下每个代码示例都显示一个部分指定的 AssemblyName,它必须由带有强名称的程序集来满足。

[C#]

com.microsoft.crypto, Culture="", PublicKeyToken=a5d015c7d5a0b012

com.microsoft.crypto, Culture=en, PublicKeyToken=a5d015c7d5a0b012,

Version=1.0.0.0

指定指针

SimpleTypeSpec* 表示非托管指针。例如,要获取指向 MyType 类型的指针,请使用 Type.GetType("MyType*")。要获取指向 MyType 类型指针的指针,请使用 Type.GetType("MyType**")。

指定引用

SimpleTypeSpec & 表示托管指针或引用。例如,要获取对 MyType 类型的引用,请使用 Type.GetType("MyType &")。请注意,与指针不同,引用仅限于一个级别。

指定数组

在 BNF 语法中,ReflectionEmitDimension 仅适用于使用 ModuleBuilder.GetType 检索的不完整类型定义。不完整的类型定义是使用 Reflection.Emit 构造的 TypeBuilder 对象(但没有对这些对象调用 TypeBuilder.CreateType)。ReflectionDimension 可用于检索任何已完成的类型定义,即已加载的类型。

通过指定数组的秩,可以访问反射中的数组。

Type.GetType("MyArray[]") 获取下限为 0 的单维数组。

Type.GetType("MyArray[*]") 获取下限未知的单维数组。

Type.GetType("MyArray[][]") 获取二维数组的数组。

Type.GetType("MyArray[*,*]") 和 Type.GetType("MyArray[,]") 获取下限未知的矩形二维数组。

请注意,从运行库的角度来看,MyArray[] != MyArray[*],但对于多维数组而言,这两者表示是等效的。也就是说,Type.GetType("MyArray [,]") == Type.GetType("MyArray[*,*]") 的计算结果为 true。

对于 ModuleBuilder.GetType,MyArray[0..5] 指示大小为 6 下限为 0 的单维数组。MyArray[4...] 指示大小未知下限为 4 的单维数组。

总结

上面是VS.NET中.NET运行时了解类型信息的一些方法和代码示例,仅供大家参考。有任何建议请MAIL我 paulni@citiz.net

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有