反射_01概述和反射中的运行时类型以及查看类型信息

反射概述

公共语言运行库加载器管理应用程序域,这些域在拥有相同应用程序范围的对象周围形成确定边界。这种管理包括将每个程序集加载到相应的应用程序域,以及控制每个程序集中类型层次结构的内存布局。

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

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

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

3)         使用 ConstructorInfo 发现以下信息:构造函数的名称、参数、访问修饰符(如 public  private)和实现详细信息(如 abstract  virtual)等。

使用 Type  GetConstructors GetConstructor 方法来调用特定的构造函数。

4)         使用 MethodInfo 发现以下信息:方法的名称、返回类型、参数、访问修饰符(如 public  private)和实现详细信息(如 abstract  virtual)等

使用 Type  GetMethods GetMethod 方法来调用特定的方法。

5)         使用 FieldInfo 发现以下信息:字段的名称、访问修饰符(如 public  private)和实现详细信息(如 static)等,并获取或设置字段值。

6)         使用 EventInfo 发现以下信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,并添加或移除事件处理程序。

7)         使用 PropertyInfo 发现以下信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,并获取或设置属性值。

8)         使用 ParameterInfo 发现以下信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。

9)         当您在一个应用程序域的仅反射上下文中工作时,请使用 CustomAttributeData 来了解有关自定义属性的信息。使用 CustomAttributeData,您不必创建属性的实例就可以检查它们。

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

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

反射还有其他一些用途。System.Runtime.Serialization 命名空间中的类使用反射来访问数据,并确定要持久保存的字段。System.Runtime.Remoting 命名空间中的类通过序列化来间接地使用反射。

反射中的运行时类型

反射提供类(例如 Type  MethodInfo)来表示类型、成员、参数和其他代码实体。但是,在您使用反射时,您并不直接使用这些类,这些类中的大多数是抽象的。 您使用的是公共语言运行时 (CLR) 提供的类型。

例如,使用 C#  typeof 运算符。获取 Type 对象时,该对象实际上是 RuntimeType RuntimeType 派生自 Type,并提供所有抽象方法的实现。

这些运行时类是 internal 它们的文档与它们的基类的文档并没有分开,因为它们的行为是由基类文档描述的。

查看类型信息

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

使用 Assembly.GetType  Assembly.GetTypes 从尚未加载的程序集中获取 Type 对象,并传入所需类型的名称。

 使用 Type.GetType 可从已加载的程序集中获取 Type 对象。

 使用Module.GetType  Module.GetTypes 可获取模块 Type 对象。

注意:如果想要检查和操作泛型类型和方法,请参见反射类型和泛型类型和如何:使用反射检查和实例化泛型类型中提供的附加信息。

下面的示例显示在获取程序集的 Assembly 对象和模块时所必需的语法。

// object 对象获得程序集mscorlib

Assembly a = typeof(object).Module.Assembly;

下面的示例说明如何从已加载的程序集中获取 Type 对象。

using System;
using System.Reflection; 
namespace AssemblyLoad
{    
	class Program    
	{        
		static void Main(string[] args)        
		{            
			// 通过文件名加载程序集            
			Assembly a = Assembly.LoadFrom("MyExe.exe");            
			// 从程序集获得类型名称            
			Type[] types2 = a.GetTypes();            
			foreach (Type t in types2)            
			{                
				Console.WriteLine(t.FullName);            
			}             
			Console.WriteLine();             
			a = Assembly.LoadFrom("MyDll.dll");            
			types2 = a.GetTypes();            
			foreach (Type t in types2)            
			{                
				Console.WriteLine(t.FullName);            
			}            
			Console.ReadKey();        
		}    
	}
}

在获取一个  Type  后,您可以采用许多方法发现与该类型的成员有关的信息。   例如,通过调用  Type.GetMembers  方法(该方法将获取对当前类型每个成员描述的一组  MemberInfo  对象),找到有关该类型的所有成员的信息。

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

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

http://i.msdn.microsoft.com/Hash/030c41d9079671d09a62d8e2c1db6973.gif System.Type ConstructorInfo

下面的示例演示如何列出一个类(此示例中为 String 类)的构造函数。

using System;
using System.Reflection; 
namespace ListConstructors
{    
	class Program    
	{        
		static void Main(string[] args)        
		{            
			Type t = typeof(System.String);            
			Console.WriteLine("正在列出类型 {0} 所有的 public 构造函数", t);            
			ConstructorInfo[] ci = t.GetConstructors(BindingFlags.Public | BindingFlags.Instance);            
			Console.WriteLine("//构造函数");            
			PrintMembers(ci);             
			Console.ReadKey();        
		}        
		public static void PrintMembers(MemberInfo[] ms)        
		{            
			foreach (MemberInfo m in ms)            
			{                
			Console.WriteLine("{0}{1}", "     ", m);            
			}            
			Console.WriteLine();        
		}    
	}
}

http://i.msdn.microsoft.com/Hash/030c41d9079671d09a62d8e2c1db6973.gifMemberInfoMethodInfoFieldInfo PropertyInfo

使用 MemberInfoMethodInfoFieldInfo  PropertyInfo 对象获取有关该类型的方法、属性、事件和字段的信息。下面的示例使用 MemberInfo 列出 System.IO.File 类中的成员数量并使用 System.Type.IsPublic 属性确定该类的可见性。

using System;
using System.IO;
using System.Reflection; 
namespace Mymemberinfo
{    
	class Program    
	{        
		static void Main(string[] args)        
		{            
			Console.WriteLine("/nReflection.MemberInfo");            
			Type MyType = Type.GetType("System.IO.File");            
			MemberInfo[] Mymemberinfoarray = MyType.GetMembers();            
			Console.WriteLine("/nThere are {0} members in {1}.", Mymemberinfoarray.Length, MyType.FullName);            
			Console.WriteLine("{0}.", MyType.FullName);            
			if (MyType.IsPublic)            
			{                
				Console.WriteLine("{0} is public.", MyType.FullName);            
			}            
			Console.ReadKey();        
		}    
	}
}

下面的示例检查指定成员的类型,检查FieldInfo 类的GetValue 方法的信息。对 MemberInfo 类的一个成员执行反射,然后列出其类型。

using System;
using System.Reflection; 
namespace MyMethodInfo
{    
	class Program    
	{        
		static void Main(string[] args)        
		{            
			Console.WriteLine("Reflection.MethodInfo");            
			Type MyType = Type.GetType("System.Reflection.FieldInfo");            
			// 指定您想要获得类型信息的成员 GetValue            
			MethodInfo Mymethodinfo = MyType.GetMethod("GetValue");            
			Console.WriteLine(MyType.FullName + "." + Mymethodinfo.Name);            
			// 获取并显示 MemberType 属性            
			MemberTypes Mymembertypes = Mymethodinfo.MemberType;            
			switch (Mymembertypes)            
			{                
				case MemberTypes.Constructor:                    
					Console.WriteLine("MemberType is of type All");                    
					break;                
				case MemberTypes.Custom:                    
					Console.WriteLine("MemberType is of type Custom");                    
					break;                
				case MemberTypes.Event:                    
					Console.WriteLine("MemberType is of type Event");                    
					break;                
				case MemberTypes.Field:                    
					Console.WriteLine("MemberType is of type Field");                    
					break;                
				case MemberTypes.Method:                    
					Console.WriteLine("MemberType is of type Method");                    
					break;                
				case MemberTypes.Property:                    
					Console.WriteLine("MemberType is of type Property");                    
					break;                
				case MemberTypes.TypeInfo:                    
					Console.WriteLine("MemberType is of type TypeInfo");                    
					break;            
			}             
			Console.ReadKey();        
		}    
	}
}

下面的示例使用反射  *Info  类以及  BindingFlags  来列出指定类的所有成员(构造函数、字段、属性、事件和方法),并将这些成员分为为静态和实例。

using System;
using System.Reflection; 
namespace ListMembers
{    
	class Program    
	{        
		static void Main(string[] args)        
		{            
			// 指定类            
			Type t = typeof(System.IO.BufferedStream);            
			Console.WriteLine("正在列出 {0} 类型所有的成员(public 和 non public)...", t);             
			// 列出 static 字段            
			FieldInfo[] fi = t.GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);            
			Console.WriteLine("// Static Fields");            
			PrintMembers(fi);             
			// 列出 Static 属性            
			PropertyInfo[] pi = t.GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);            
			Console.WriteLine("// Static Properties");            
			PrintMembers(pi);             
			// 列出 Static 事件            
			EventInfo[] ei = t.GetEvents(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);            
			Console.WriteLine("// Static Events");            
			PrintMembers(ei);             
			// 列出 Static 方法            
			MethodInfo[] mi = t.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);            
			Console.WriteLine("// Static Methods");            
			PrintMembers(mi);             
			// 列出 Constructors            
			ConstructorInfo[] ci = t.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);            
			Console.WriteLine("// Constructors");            
			PrintMembers(ci);             
			// 列出 Instance 字段            
			fi = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);            
			Console.WriteLine("// Instance Fields");            
			PrintMembers(fi);             
			// 列出 Instance 属性            
			pi = t.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);            
			Console.WriteLine("// Instance Properties");            
			PrintMembers(pi);             
			// 列出 Instance 事件            
			ei = t.GetEvents(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);            
			Console.WriteLine("// Instance Events");            
			PrintMembers(ei);             
			// 列出 Instance 方法            
			mi = t.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);            
			Console.WriteLine("// Instance Methods");            
			PrintMembers(mi);             
			Console.ReadKey();        
		}         
		public static void PrintMembers(MemberInfo[] ms)        
		{            
			foreach (MemberInfo m in ms)            
			{                
				Console.WriteLine("{0}{1}", "     ", m);            
			}            
			Console.WriteLine();        
		}    
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值