您的位置:首页 > 其它

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

2002-04-18 09:26 495 查看
通过反射命名空间中的类以及System.Type,您可以获取有关已加载的程序集和在其中定义的类型(如类、接口和值类型)的信息。您也可以使用反射在运行时创建类型实例,然后调用和访问这些实例。

反射概述

公共语言运行库加载器管理应用程序域。这种管理包括将每个程序集加载到相应的应用程序域以及控制每个程序集中类型层次结构的内存布局。

程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。反射通常具有以下用途:

使用Assembly定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。

使用Module了解如下的类似信息:包含模块的程序集以及模块中的类等。您还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。

使用ConstructorInfo了解如下的类似信息:构造函数的名称、参数、访问修饰符(如publicprivate)和实现详细信息(如abstractvirtual)等。使用Type对象的GetConstructors或GetConstructor方法来调用特定的构造函数。

使用MethodInfo来了解如下的类似信息:方法的名称、返回类型、参数、访问修饰符(如publicprivate)和实现详细信息(如abstractvirtual)等。使用Type对象的GetMethods或GetMethod方法来调用特定的方法。

使用FieldInfo来了解如下的类似信息:字段的名称、访问修饰符(如publicprivate)和实现详细信息(如static)等;并获取或设置字段值。

使用EventInfo来了解如下的类似信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。

使用PropertyInfo来了解如下的类似信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。

使用ParameterInfo来了解如下的类似信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。

System.Reflection.Emit命名空间的类提供了一种特殊形式的反射,使您能够在运行时构造类型。

反射也可用于创建称作类型浏览器的应用程序,它使用户能够选择类型,然后查看有关选定类型的信息。

反射还有其他一些用途。JScript等语言编译器使用反射来构造符号表。System.Runtime.Serialization命名空间中的类使用反射来访问数据并确定要持久保存的字段。System.Runtime.Remoting命名空间中的类通过序列化来间接地使用反射。

查看类型信息

System.Type类对于反射起着核心的作用。当反射请求加载的类型时,公共语言运行库将为它创建一个Type对象。您可以使用Type对象的方法、字段、属性和嵌套类来查找有关该类型的所有信息。

在使用Assembly.GetType或Assembly.GetTypes时传入所需类型的名称,可以从尚未加载的程序集中获取Type对象。使用Type.GetType可从已加载的程序集中获取Type对象。使用Module.GetType和Module.GetTypes可获取模块Type对象。

以下代码示例显示在获取程序集的Assembly对象和模块时所必需的语法。
[C#]
//Getthemscorlibassemblyinwhichtheobjectisdefined.
Assemblya=typeof(Object).Module.Assembly;


以下示例代码说明如何从已加载的程序集中获取Type对象。
[C#]
//Loadanassemblyusingitsfilename.
Assemblya=Assembly.LoadFrom("MyExe.exe");
//Getthetypenamesfromtheassembly.
Type[]types2=a.GetTypes();
foreach(Typetintypes2)
{
Console.WriteLine(t.FullName);
}


获取Type对象之后,可以通过多种方法来了解有关该类型成员的信息。例如,通过调用Type.GetMembers方法(该方法将获取对当前类型的每个成员进行描述的一组MemberInfo对象),您可以获取有关该类型的所有成员的信息。

您也可以在Type类上使用方法,以检索有关按名称指定的一个或多个构造函数、方法、事件、字段或属性的信息。例如,Type.GetConstructor封装当前类的特定构造函数。

如果具有Type对象,则可以使用Type.Module属性来获取一个封装该类型所在模块的对象。使用Module.Assembly属性可查找封装模块所在程序集的对象。使用Type.Assembly属性可直接获取封装类型的程序集。

System.Type和ConstructorInfo

以下代码示例显示如何列出一个类(此示例中为String类)的构造函数。
[C#]
//Thisprogramlistsallthepublicconstructors
//oftheSystem.Stringclass.
usingSystem;
usingSystem.Reflection;
classListMembers{
publicstaticvoidMain(String[]args){
Typet=typeof(System.String);
Console.WriteLine("Listingallthepublicconstructorsofthe{0}type",t);
//Constructors
ConstructorInfo[]ci=t.GetConstructors(BindingFlags.Public|BindingFlags.Instance);
Console.WriteLine("//Constructors");
PrintMembers(ci);
}
publicstaticvoidPrintMembers(MemberInfo[]ms){
foreach(MemberInfominms){
Console.WriteLine("{0}{1}","",m);
}
Console.WriteLine();
}
}


MemberInfo、MethodInfo、FieldInfo和PropertyInfo

使用MemberInfo、MethodInfo、FieldInfo或PropertyInfo对象可获取有关类型的方法、属性、事件、字段的信息。

以下代码示例使用MemberInfo来列出System.IO.File类中的成员数量并使用System.Type.IsPublic属性来确定该类的可见性。
[C#]
usingSystem;
usingSystem.IO;
usingSystem.Reflection;
classMymemberinfo
{
publicstaticvoidMain(string[]args)
{
Console.WriteLine("/nReflection.MemberInfo");
//GettheTypeandMemberInfo.
TypeMyType=Type.GetType("System.IO.File");
MemberInfo[]Mymemberinfoarray=MyType.GetMembers();
//GetanddisplaytheDeclaringTypemethod.
Console.WriteLine("/nThereare{0}membersin{1}.",
Mymemberinfoarray.Length,MyType.FullName);
Console.WriteLine("{0}.",MyType.FullName);
if(MyType.IsPublic)
{
Console.WriteLine("{0}ispublic.",MyType.FullName);
}
}
}


以下代码示例调查指定成员的类型。它对MemberInfo类的一个成员执行反射,然后列出其类型。
[C#]
//ThiscodedisplaysinformationabouttheGetValuemethodofFieldInfo.
usingSystem;
usingSystem.Reflection;
classMyMethodInfo{
publicstaticintMain(){
Console.WriteLine("Reflection.MethodInfo");
//GetanddisplaytheType.
TypeMyType=Type.GetType("System.Reflection.FieldInfo");
//Specifythememberforwhichyouwanttypeinformationhere.
MethodInfoMymethodinfo=MyType.GetMethod("GetValue");
Console.WriteLine(MyType.FullName+"."+Mymethodinfo.Name);
//GetanddisplaytheMemberTypeproperty.
MemberTypesMymembertypes=Mymethodinfo.MemberType;
if(MemberTypes.Constructor==Mymembertypes){
Console.WriteLine("MemberTypeisoftypeAll");
}
elseif(MemberTypes.Custom==Mymembertypes){
Console.WriteLine("MemberTypeisoftypeCustom");
}
elseif(MemberTypes.Event==Mymembertypes){
Console.WriteLine("MemberTypeisoftypeEvent");
}
elseif(MemberTypes.Field==Mymembertypes){
Console.WriteLine("MemberTypeisoftypeField");
}
elseif(MemberTypes.Method==Mymembertypes){
Console.WriteLine("MemberTypeisoftypeMethod");
}
elseif(MemberTypes.Property==Mymembertypes){
Console.WriteLine("MemberTypeisoftypeProperty");
}
elseif(MemberTypes.TypeInfo==Mymembertypes){
Console.WriteLine("MemberTypeisoftypeTypeInfo");
}
return0;
}
}


以下示例代码使用所有的反射*Info类以及BindingFlags来列出指定类的所有成员(构造函数、字段、属性、事件和方法),并将这些成员划分为静态和实例类别。
[C#]
//Thisprogramlistsallthemembersofthe
//System.IO.BufferedStreamclass.
usingSystem;
usingSystem.IO;
usingSystem.Reflection;
classListMembers{
publicstaticvoidMain(String[]args){
//Specifytheclasshere.
Typet=typeof(System.IO.BufferedStream);
Console.WriteLine("Listingallthemembers(publicandnonpublic)ofthe{0}type",t);
//StaticFieldsarelistedfirst.
FieldInfo[]fi=t.GetFields(BindingFlags.Static|
BindingFlags.NonPublic|BindingFlags.Public);
Console.WriteLine("//StaticFields");
PrintMembers(fi);
//StaticProperties
PropertyInfo[]pi=t.GetProperties(BindingFlags.Static|
BindingFlags.NonPublic|BindingFlags.Public);
Console.WriteLine("//StaticProperties");
PrintMembers(pi);
//StaticEvents
EventInfo[]ei=t.GetEvents(BindingFlags.Static|
BindingFlags.NonPublic|BindingFlags.Public);
Console.WriteLine("//StaticEvents");
PrintMembers(ei);
//StaticMethods
MethodInfo[]mi=t.GetMethods(BindingFlags.Static|
BindingFlags.NonPublic|BindingFlags.Public);
Console.WriteLine("//StaticMethods");
PrintMembers(mi);
//Constructors
ConstructorInfo[]ci=t.GetConstructors(BindingFlags.Instance|
BindingFlags.NonPublic|BindingFlags.Public);
Console.WriteLine("//Constructors");
PrintMembers(ci);
//InstanceFields
fi=t.GetFields(BindingFlags.Instance|BindingFlags.NonPublic|
BindingFlags.Public);
Console.WriteLine("//InstanceFields");
PrintMembers(fi);
//InstanceProperites
pi=t.GetProperties(BindingFlags.Instance|BindingFlags.NonPublic|
BindingFlags.Public);
Console.WriteLine("//InstanceProperties");
PrintMembers(pi);
//InstanceEvents
ei=t.GetEvents(BindingFlags.Instance|BindingFlags.NonPublic|
BindingFlags.Public);
Console.WriteLine("//InstanceEvents");
PrintMembers(ei);
//InstanceMethods
mi=t.GetMethods(BindingFlags.Instance|BindingFlags.NonPublic|
BindingFlags.Public);
Console.WriteLine("//InstanceMethods");
PrintMembers(mi);
Console.WriteLine("/r/nPressReturntoexit.");
Console.Read();
}
publicstaticvoidPrintMembers(MemberInfo[]ms){
foreach(MemberInfominms){
Console.WriteLine("{0}{1}","",m);
}
Console.WriteLine();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: