反射的基础概念:
反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。还可以获得每个成员的名称、限定符和参数等。有了反射,即可对每一个类型了如指掌。如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道。
NET可执行应用程序结构 :
程序代码在编译后生成可执行的应用,我们首先要了解这种可执行应用程序的结构。
应用程序结构分为应用程序域—程序集—模块—类型—成员几个层次,公共语言运行库加载器管理应用程序域,这种管理包括将每个程序集加载到相应的应用程序域以及控制每个程序集中类型层次结构的内存布局。
程序集包含模块,而模块包含类型,类型又包含成员,反射则提供了封装程序集、模块和类型的对象。我们可以使用反射动态地创建类型的实例,将类型绑定到现有对象或从现有对象中获取类型,然后调用类型的方法或访问其字段和属性。反射通常具有以下用途。
(1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
(2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其它特定的非全局方法。
(3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数。
(4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。
(5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
(6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
(7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
(8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
System.Reflection.Emit命名空间的类提供了一种特殊形式的反射,可以在运行时构造类型。
反射也可用于创建称为类型浏览器的应用程序,使用户能够选择类型,然后查看有关选定类型的信息。
此外,Jscript等语言编译器使用反射来构造符号表。System.Runtime.Serialization命名空间中的类使用反射来访问数据并确定要永久保存的字段,System.Runtime.Remoting命名空间中的类通过序列化来间接地使用反射。
( 1 ) 反射什么时候可以使用:
使用反射工厂的优点是极大地减少了工厂类的数量、降低了代码的冗余,并且系统更容易扩展,在增加新类型后,不需要修改工厂类。理论上可以用一个工厂完成很多类型的实例化。多类型的实例化可以通过反射轻松实现。
但是,相应地反射得消耗是非常大的,使用时应该首先考虑清楚这一点。
( 2 )反射入门(一些简单实例)
实例1:
在程序去得时动态实例化对象,获得对象的属性,并调用对象的方法。
1Namespace ReflectionExample
2{
3 class Class1
4 {
5 [STAThread]
6 static void Main (string [ ] args)
7 {
8 System.Console.WriteLine(“列出程序集中的所有类型”);
9 Assembly a = Assembly.LoadFrom (“ReflectionExample.exe”);
10 Type[ ] mytypes = a.GetTypes( );
11
12 Foreach (Type t in mytypes) //循环所有类型Type
13 {
14 System.Console.WriteLine ( t.Name );
15 }
16 System.Console.ReadLine ( );
17 System.Console.WriteLine (“列出HellWord中的所有方法” );
18 Type ht = typeof(HelloWorld);
19 MethodInfo[] mif = ht.GetMethods();
20 foreach(MethodInfo mf in mif) //循环所有方法MethodInfo[]
21 {
22 System.Console.WriteLine(mf.Name);
23 }
24 System.Console.ReadLine();
25 System.Console.WriteLine("实例化HelloWorld,并调用SayHello方法");
26 Object obj = Activator.CreateInstance(ht);
27 string[] s = {"zhenlei"};
28 Object bojName = Activator.CreateInstance(ht,s); // 实例化CreateInstance
29 BindingFlags flags = (BindingFlags.NonPublic|BindingFlags.Public|BindingFlags.Static|BindingFlags.Instance|BindingFlags.DeclaredOnly);
30 MethodInfo msayhello = ht.GetMethod("SayHello");
31 msayhello.Invoke(obj,null); //调用方法Invoke
32 msayhello.Invoke(objName,null);
33 System.Console.ReadLine();
34 }
35 }
36}
1using System; //被使用的Dll
2namespace ReflectionExample
3{
4 public class HelloWorld
5 {
6 string myName = null;
7 public HelloWorld(string name)
8 {
9 myName = name;
10 }
11 public HelloWorld() : this(null)
12 {}
13 public string Name
14 {
15 get
16 {
17 return myName;
18 }
19 }
20 public void SayHello()
21 {
22 if(myName == null)
23 {
24 System.Console.WriteLine("Hello World");
25 }
26 else
27 {
28 System.Console.WriteLine("Hello," + myName);
29 }
30 }
31 }
32}
33
实例2:
用反射调用任意.net库中的方法(函数中含详尽解述)
函数如下:ReturnMessage自定议类
2、通过NameSpaceAndClassName和MethodName实际上就可以精确定位一个方法了如调用abc.dll里的namespace1.Class1.Main,调用起来就是CallAssembly("abc.dll","namespace1.Class1","Main",null)
public static ReturnMessage CallAssembly(string Path,string NameSpaceAndClassName,string MethodName,object[] Parameters)
{
try
{
Assembly Ass=Assembly.LoadFrom(Path);//调入文件(不限于dll,exe亦可,只要是.net)
Type TP=Ass.GetType(NameSpaceAndClassName);//NameSpaceAndClassName是"名字空间.类名",如"namespace1.Class1"
MethodInfo MI=TP.GetMethod(MethodName);//MethodName是要调用的方法名,如"Main"
object MeObj=System.Activator.CreateInstance(TP);
MI.Invoke(MeObj,Parameters);//Parameters是调用目标方法时传入的参数列表
return new ReturnMessage(true,"成功调用",1);
}
catch(Exception e)
{
return new ReturnMessage(false,"出现异常,消息为:"+e.Message,-1,e);
}
}
实例3:
(1)namespace ClassLibrarySport
{
public abstract class Sport
{
protected string name;
public abstract string GetName();
public abstract string GetDuration();
}
}
= = = = = == = == = == = == = == = == = == = == = == = == = == = == = == = == =
(2)
namespace ClassLibrarySomeSports//该项目添加了对(1)的引用
{
public class Football : ClassLibrarySport.Sport
{
public Football()
{
name = "Football";
}
public override string GetName()
{
return name;
}
public override string GetDuration()
{
return "four 15 minute quarters";
}
}
}
= = = = = == = == = == = == = == = == = == = == = == = == = == = == = == = == =
(3)namespace ConsoleAssemblyTest//该项目添加了对(1)的引用
{
class Program
{
static void Main(string[] args)
{
Assembly assembly = Assembly.LoadFrom(@"E:\ClassLibrarySomeSports\bin\Debug\ClassLibrarySomeSports.dll");
<span
分享到:
相关推荐
Unity Planar Reflection平面反射
反射(Reflection)是C#里很重要的一个特性,源码是我写的一篇关于反射的文章的示例,有详细的解释,是学习反射的好实例。
供初学反射的开发者提供一个小例子,希望各位多多指点
反射可以有很多方法,编写程序时请先导入 System.Reflection 命名空间。 1、假设你要反射一个 DLL 中的类,并且没有引用它(即未知的类型): Assembly assembly = Assembly.LoadFile(程序集路径,不能是...
圣思园 reflection(Java反射) 课件 圣思园 reflection(Java反射) 课件 圣思园 reflection(Java反射) 课件
Java Reflection (JAVA反射)详解
Java反射经典实例 Java Reflection Cookbook[1].docx.pdf
北大青鸟ACCP6.0 第三学期 Y2 JAVA方向 reflection 反射 基础复习 上课示例
反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。还可以获得每个成员的名称、限定符和...
C# 反射实例代码 接口方式动态加载dllReflectionC# 反射实例代码 接口方式动态加载dllReflection
Java Reflection (JAVA反射.mht
C#反射(Reflection)详解 什么是反射 命名空间和装配体的关系
C# 反射例ReflectionExample C# 反射例ReflectionExample C# 反射例ReflectionExample
C#反射其它DLL的封装应用,支持方法、参数、对象的调用。
c# 反射(Reflection)例子
Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java...JavaBean 是 reflection 的实际应用之一,它能让一些工具可视化的操作软件组件。这些工具通过 reflection 动态的载入并取得 Java 组件(类) 的属性。
Java反射机制的实现_Reflection,适合学习了解反射机制。
之前上课的时候老师总结的JavaReflection反射学习资料,内容简单易懂,浅显易懂,适合小白入手学习。。
轻松掌握java反射技术,虽然讲得比较简单,但是通俗易懂。
Reflection in Java. 介绍Java中的反射机制,候捷谈Java反射机制