【转载】C#反射机制详解
反射的定义:审查元数据并收集关於它的类型信息的能力,元数据(编辑后的基本数据单元)就是一大堆表,编译器会创建一个类定义表,一个字段定义表,一个方法定义表等,System.Reflection命名空间包含的几个类,允许你反射(解析)这些元数据的代码
一、反射的作用:
动态的创建类型的实例,将类型邦定到现有对象,或从现有对象中获取类型
应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射
反射主要应用於类库,这些类库需要知道一个类型的定义,以便提供更多的功能
二、应用要点:
现实应用程序中很少使用到反射
使用反射动态邦定需要牺牲性能
有些元数据信息是不能通过反射获取的
某些反射类型是专门為那些CLR开发编辑器开发使用的,所以你要意思到不是所有反射类型都是可以使用的
三、取得Assembly的方法:
Assembly.Load
Assembly.LoadFile
Assembly.LoadFrom
Type对象的Assembly方法
四、反射的成员:
MemberInfo-成员
ConstructorInfo-结构
FieldInfo-字段
MethodInfo-方法
PropertyInfo-属性
EventInfo-事件
五、根据反射取得对象的Member信息
private void WriteReflectionInfo()
{
Type testType = typeof(Test);
Assembly assembly = testType.Assembly;
Response.Write("Assembly:" + assembly.FullName + "<br/>");
Type[] typeList = assembly.GetTypes(); // 获取类型
// 针对每个类型获取详细信息
foreach (Type type in typeList)
{
Response.Write("------------------------" + type.Namespace + type.Name + "------------------------<br/>");
// 获得类型的结构信息
ConstructorInfo[] constructs = type.GetConstructors();
// 获得类型的字段信息
FieldInfo[] fields = type.GetFields();
Response.Write("<b>类的公共字段信息如下:</b>" + "<br/>");
int a1 = 1;
foreach (FieldInfo field in fields)
{
Response.Write((a1++).ToString() + ". " + field.Name + "<br/>");
}
// 获得方法信息
MethodInfo[] methods = type.GetMethods();
Response.Write("<b>类的公共方法如下:</b>" + "<br/>");
int a2 = 1;
foreach (MethodInfo method in methods)
{
ParameterInfo[] parameters = method.GetParameters();
ParameterInfo reparam = method.ReturnParameter;
Response.Write((a2++).ToString() + ". " + reparam.ParameterType.Name + " " + method.Name + "(");
int index = 0;
foreach (ParameterInfo para in parameters)
{
if (index++ < parameters.Length - 1)
Response.Write(para.ParameterType.Name + " " + para.Name + ",");
else
Response.Write(para.ParameterType.Name + " " + para.Name);
}
Response.Write(")<br/>");
}
// 获得属性的信息
PropertyInfo[] propertys = type.GetProperties();
Response.Write("<b>类的公共属性如下:</b>" + "<br/>");
int a3 = 1;
foreach (PropertyInfo pro in propertys)
{
Response.Write((a3++).ToString() + ". " + pro.PropertyType.Name + " " + pro.Name + "{");
if (pro.CanRead) Response.Write("get;");
if (pro.CanWrite) Response.Write("set;");
Response.Write("}<br/>");
}
// 获得事件信息
EventInfo[] events = type.GetEvents();
Response.Write("<b>类的成员如下:</b>" + "<br/>");
// 获得成员
int a4 = 1;
foreach (MemberInfo mi in type.GetMembers())
{
Response.Write((a4++).ToString() + ". " + mi.MemberType.ToString() + " : " + mi.Name + "<br/>");
}
}
六、动态创建对象
Assembly对象的 CreateInstance方法
Activator. CreateInstance方法
Type对象的 InvokeMember方法
// 使用Assembly的CreateInstance方法来取得对象的实例
private void Assembly_CreateInstance()
{
string assemblyName = "SqlModel";
string className = assemblyName + ".Member";
// 创建无参数实例
IDAL.IMember member = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className);
Response.Write("创建无参数实例:" + member.ID + "<br/>");
// 创建有参数实例
Object[] parameters = new Object[1];
parameters[0] = 10000;
IDAL.IMember member1 = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className, false, BindingFlags.Default, null, parameters, null, null);
Response.Write("创建有参数实例:" + member1.ID + "<br/>");
}
// 使用Activator的CreateInstance方法来取得对象的实例
private void Activator_CreateInstance()
{
string assemblyName = "SqlModel";
string className = assemblyName + ".Member";
// 创建无参数实例
System.Runtime.Remoting.ObjectHandle obj = Activator.CreateInstance(assemblyName, className);
IDAL.IMember member = (IDAL.IMember)obj.Unwrap();
Response.Write("创建无参数实例:" + member.ID + "<br/>");
// 创建有参数实例
Object[] parameters = new Object[1];
parameters[0] = 10000;
System.Runtime.Remoting.ObjectHandle obj1 = Activator.CreateInstance(assemblyName, className, false, BindingFlags.CreateInstance, null, parameters, null, null, null);
IDAL.IMember member1 = (IDAL.IMember)obj1.Unwrap();
Response.Write("创建有参数实例:" + member1.ID + "<br/>");
}
// 使用Type的InvokeMember方法来取得对象的实例
private void Type_InvokeMember()
{
string assemblyName = "SqlModel";
string className = assemblyName + ".Member";
Assembly assem = Assembly.Load(assemblyName);
Type type = assem.GetType(className); // 註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的
// 创建无参数实例
IDAL.IMember member = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, null);
Response.Write("创建无参数实例:" + member.ID + "<br/>");
// 创建有参数实例
Object[] parameters = new Object[1];
parameters[0] = 10000;
IDAL.IMember member1 = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, parameters);
Response.Write("创建有参数实例:" + member1.ID + "<br/>");
}
七、动态调用对象方法
Type对象的 InvokeMember方法
MethodInfo对象的Invoke方法
// Type对象的 InvokeMember方法来动态调用方法
private void InvokeMember()
{
string assemblyName = "SqlModel";
string className = assemblyName + ".Member";
string methodName = String.Empty;
string result = String.Empty;
Assembly assem = Assembly.Load(assemblyName);
Object obj = assem.CreateInstance(className);
Type type = assem.GetType(className); // 註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的
// 动态调用无参数的方法
methodName = "GetName";
result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, null);
Response.Write(methodName + "方法的返回值:" + result + "<br/>");
// 动态调用有参数的方法
methodName = "Update";
Object[] methodParams = new Object[1];
methodParams[0] = DateTime.Now;
result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams);
Response.Write(methodName + "方法的返回值:" + result + "<br/>");
// 动态调用参数构架函数的带有参数的方法
Object[] parameters = new Object[1];
parameters[0] = 10000;
obj = assem.CreateInstance(className,false,BindingFlags.CreateInstance, null, parameters, null, null);
result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams);
Response.Write(methodName + "方法的返回值:" + result + "<br/>");
}
// MethodInfo对象的Invoke方法来动态调用方法
private void MethodInfo_Invoke()
{
string assemblyName = "SqlModel";
string className = assemblyName + ".Member";
string methodName = String.Empty;
string result = String.Empty;
Assembly assem = Assembly.Load(assemblyName);
Object obj = assem.CreateInstance(className);
Type type = assem.GetType(className); // 註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的
// 动态调用无参数的方法
methodName = "GetName";
MethodInfo methodInfo = type.GetMethod(methodName);
result = (string)methodInfo.Invoke(obj, null);
Response.Write(methodName + "方法的返回值:" + result + "<br/>");
// 动态调用有参数的方法
methodName = "Update";
Object[] methodParams = new Object[1];
methodParams[0] = DateTime.Now;
MethodInfo method = type.GetMethod(methodName);
result = (string)method.Invoke(obj, methodParams);
Response.Write(methodName + "方法的返回值:" + result + "<br/>");
}
--------------------------------------------------------------------------------
以上所使用的SqlModel.Member為:
新建一个SqlModel类库,在其下建立一个Member的类
namespace SqlModel
{
public class Member : IDAL.IMember
{
private int _id = 100;
public int ID
{
get { return _id; }
set { _id = value; }
}
private string _name = "limin";
public string Name
{
get { return _name; }
set { _name = value; }
}
public Member() { }
public Member(int id)
{
_id = id;
}
private void Init()
{ }
public string GetName()
{
return _name;
}
public string Update (DateTime cdate)
{
return "{" + String.Format("ID:{0},Name:{1},CreateDate:{2}",_id,_name,cdate) + "}";
}
}
}
【转载】C#反射机制详解的更多相关文章
- Java 反射机制详解(下)
续:Java 反射机制详解(上) 三.怎么使用反射 想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属 ...
- Java 反射机制详解(上)
一.什么是反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java ...
- 【转载】Java反射机制详解
转自:http://baike.xsoftlab.net/view/209.html#3_8 1反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对 ...
- Java反射机制详解
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反 ...
- Java中反射机制详解
序言 在学习java基础时,由于学的不扎实,讲的实用性不强,就觉得没用,很多重要的知识就那样一笔带过了,像这个马上要讲的反射机制一样,当时学的时候就忽略了,到后来学习的知识中,很多东西动不动就用反射, ...
- java反射机制详解 及 Method.invoke解释
JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为ja ...
- Java 反射机制详解
动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化.比如众所周知的ECMAScript(JavaScript)便是一个动态语言.除此之外如Ru ...
- Java反射机制详解(3) -java的反射和代理实现IOC模式 模拟spring
IOC(Inverse of Control) 可翻译为“控制反转”,但大多数人都习惯将它称为“依赖注入”.在Spring中,通过IOC可以将实现类.参数信息等配置在其对应的配置文件中,那么当 需要更 ...
- Java反射机制详解(1) -反射定义
首先,我们在开始前提出一个问题: 1.在运行时,对于一个java类,能否知道属性和方法:能否去调用它的任意方法? 答案是肯定的. 本节所有目录如下: 什么是JAVA的反射机制 JDK中提供的Refle ...
- [转]Java反射机制详解
目录 1反射机制是什么 2反射机制能做什么 3反射机制的相关API ·通过一个对象获得完整的包名和类名 ·实例化Class类对象 ·获取一个对象的父类与实现的接口 ·获取某个类中的全部构造函数 - 详 ...
随机推荐
- 【多线程】死锁与Java栈跟踪工具
今天面试有一道题,写一个死锁的程序,自己也是短路了,没写出来,回来写下. 死锁常见的情况是A线程持有a锁.阻塞于b锁,B线程持有b锁,阻塞于a锁,形成一个循环阻塞的状态. import java.ut ...
- [DIOCP3-IocpTask说明书]基于IOCP引擎的多线程任务的投递和回调处理单元
[说明] IocpTask是基于Iocp引擎的多线程任务投递和处理单元,可以方便的把任务进行投递到IOCP线程进行统一调度和处理,是模仿QDAC-QWorker的处理方式,支持D7以上的版本. [使用 ...
- JVM垃圾回收--年轻代、年老点和持久代
关键字约定 Young generation –>新生代 Tenured / Old Generation –>老年代 Perm Area –>永久代 年轻代: 所有新生成的对象首先 ...
- Lintcode: Majority Number 解题报告
Majority Number 原题链接:http://lintcode.com/en/problem/majority-number/# Given an array of integers, th ...
- Python中斐波那契数列的四种写法
在这些时候,我可以附和着笑,项目经理是决不责备的.而且项目经理见了孔乙己,也每每这样问他,引人发笑.孔乙己自己知道不能和他们谈天,便只好向新人说话.有一回对我说道,“你学过数据结构吗?”我略略点一点头 ...
- 阿里云安装elastcsearch后外网访问配置
内存 elastcsearch需要的内存是2G,可以修改/etc/elasticsearch/jvm.options,Xms和Xmx,建议分配更多的内存 外网访问 修改 /etc/elasticsea ...
- python 高级知识点
1.切片:截取List,tuple指定范围内的值:>>L[0,3] 2.如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Ite ...
- C语言 · 栅格打印问题
算法提高 栅格打印问题 时间限制:1.0s 内存限制:512.0MB 问题描述 编写一个程序,输入两个整数,作为栅格的高度和宽度,然后用“+”.“-”和“|”这三个字符来打印一个栅格 ...
- JDK自带观察者的使用
被观察者 package observerForJDK; import java.util.Observable; /** * 新闻派发器,当有新的新闻时派发给所有的订阅读者(观察者) */ publ ...
- Java NIO 系列教程 <转>
Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(B ...