学习笔记-用反射动态给接口实现类

问题描述

usingSystem;usingSystem.Reflection;usingSystem.Reflection.Emit;publicinterfaceIAnimal{voidmove();voideat();}publicclassTypeCreator{privateTypetargetType;///<summary>///构造函数///</summary>///<paramname="targetType">被实现或者继承的类型</param>publicTypeCreator(TypetargetType){this.targetType=targetType;}publicTypebuild(){//获取当前AppDomainAppDomaincurrentAppDomain=AppDomain.CurrentDomain;//System.Reflection.AssemblyName是用来表示一个Assembly的完整名称的AssemblyNameassyName=newAssemblyName();//为要创建的Assembly定义一个名称(这里忽略版本号,Culture等信息)assyName.Name="MyAssyFor_"+targetType.Name;//获取AssemblyBuilder//AssemblyBuilderAccess有Run,Save,RunAndSave三个取值AssemblyBuilderassyBuilder=currentAppDomain.DefineDynamicAssembly(assyName,AssemblyBuilderAccess.Run);//获取ModuleBuilder,提供String参数作为Module名称,随便设一个ModuleBuildermodBuilder=assyBuilder.DefineDynamicModule("MyModFor_"+targetType.Name);//新类型的名称:随便定一个StringnewTypeName="Imp_"+targetType.Name;//新类型的属性:要创建的是Class,而非Interface,AbstractClass等,而且是Public的TypeAttributesnewTypeAttribute=TypeAttributes.Class|TypeAttributes.Public;//声明要创建的新类型的父类型TypenewTypeParent;//声明要创建的新类型要实现的接口Type[]newTypeInterfaces;//对于基类型是否为接口,作不同处理if(targetType.IsInterface){newTypeParent=null;newTypeInterfaces=newType[]{targetType};}else{newTypeParent=targetType;newTypeInterfaces=newType[0];}//得到类型生成器TypeBuildertypeBuilder=modBuilder.DefineType(newTypeName,newTypeAttribute,newTypeParent,newTypeInterfaces);//以下将为新类型声明方法:新类型应该override基类型的所以virtual方法//得到基类型的所有方法MethodInfo[]targetMethods=targetType.GetMethods();//遍历各个方法,对于Virtual的方法,获取其签名,作为新类型的方法foreach(MethodInfotargetMethodintargetMethods){//只挑出virtual的方法if(targetMethod.IsVirtual){//得到方法的各个参数的类型ParameterInfo[]paramInfo=targetMethod.GetParameters();Type[]paramType=newType[paramInfo.Length];for(inti=0;i<paramInfo.Length;i++)paramType[i]=paramInfo[i].ParameterType;//传入方法签名,得到方法生成器MethodBuildermethodBuilder=typeBuilder.DefineMethod(targetMethod.Name,MethodAttributes.Public|MethodAttributes.Virtual,targetMethod.ReturnType,paramType);//由于要生成的是具体类,所以方法的实现是必不可少的。而方法的实现是通过EmitIL代码来产生的//得到IL生成器ILGeneratorilGen=methodBuilder.GetILGenerator();//以下三行相当于:{Console.Writeln("I'm"+targetMethod.Name+"ing");}ilGen.Emit(OpCodes.Ldstr,"I'm"+targetMethod.Name+"ing");ilGen.Emit(OpCodes.Call,typeof(Console).GetMethod("WriteLine",newType[]{typeof(String)}));ilGen.Emit(OpCodes.Ret);}}//真正创建,并返回return(typeBuilder.CreateType());}}//好了,测试一下试试看:publicclassTester{publicstaticvoidMain(String[]args){TypeCreatortc=newTypeCreator(typeof(IAnimal));Typet=tc.build();IAnimalanimal=(IAnimal)Activator.CreateInstance(t);animal.move();animal.eat();Console.Read();}}

解决方案

解决方案二:
转载自:
解决方案三:
装箱,拆箱以及反射:http://blog.programfan.com/article.asp?id=16780

解决方案四:
当泛型的参数类型是动态的:
解决方案五:
UP
解决方案六:
看了楼主的一些帖子,觉得楼主很执着...很适合学这个啊,我就懒多了,啥啥不会,不遇到就不会...
解决方案七:
我也一样,能解决就行了,不管其它的

时间: 2024-10-25 04:37:54

学习笔记-用反射动态给接口实现类的相关文章

Spring学习笔记之aop动态代理(3)

Spring学习笔记之aop动态代理(3) 1.0 静态代理模式的缺点: 1.在该系统中有多少的dao就的写多少的proxy,麻烦 2.如果目标接口有方法的改动,则proxy也需要改动. PersonDao.java public interface PersonDao { public void savePerson(); } PersonDaoImpl.java public class PersonDaoImpl implements PersonDao{ public void save

PHP通过反射动态加载第三方类和获得类源码的实例_php实例

使用反射动态加载第三方类 用反射加载第三方类用处在于: 使用XML或其他配文件配置要加载的类,从而和系统源代码分离. 对加载的类进行类检查,是加载的类符合自己定义的结构. <?php abstract class Module { #核心Module类库 function baseFunc() { echo "I am baseFunc"; } abstract function execute(); } class ModuleRunner { private $configD

java基础学习笔记之反射_java

反射 反射:将类的属性和方法映射成相应的类. 反射基本使用 获取Class类的三种方法: 类名.class 对象名.getClass() Class.forName("要加载的类名") 根据API写就行了,大致流程就是: 用上述三种方式之一获取特定类的Class类,即该类对应的字节码 调用Class对象的getConstructor(Class<?>... parameterTypes)获取构造方法对象 调用是构造方法类Constructor的newInstance(Obj

动态库接口 模版类-C++模版类是否可以作为动态库接口

问题描述 C++模版类是否可以作为动态库接口 C++模版类是否可以作为动态库接口,怎么实现,现在弄出来 template extern "C" __declspec(dllexport) class IDlgT { }; error C2988: 不可识别的模板声明/定义 不能的话请说下原因,不需要解决方式 解决方案 一个原因是模版类都是在头文件中,而你通过dll导出也需要提供头文件,那么你还导出干嘛,别人可以直接用头文件来实例化你的模版类 http://stackoverflow.c

spring学习笔记(2)文件资源访问接口Resource

spring 资源抽象接口下的几个常用实现类 实现类 说明 ClassPathResource 类路径下的资源,资源以相对类路径的方式表示 FileSystemResource 文件系统资源,资源以文件系统路径的的方式表示,如/home/root/test.txt ServletContextResource 为访问web上下文中的资源而设计的类,负责以相对于web应用根目录的路径加载资源,它支持以流和URL的方式访问,在war解包情况下,也可以通过File的方式访问,该类还可以直接从jar包中

PHP 面向对象程序设计(oop)学习笔记(一) - 抽象类、对象接口、instanceof 和契约式编程_php实例

1.PHP中的抽象类 PHP 5 支持抽象类和抽象方法.定义为抽象的类不能被实例化.任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的.被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现.在类的声明中使用 abstract 修饰符可以将某个类声明为抽象的. 可以这样理解,抽象类作为一个基类,它把特定的细节留给继承者来实现.通过抽象概念,可以在开发项目中创建扩展性很好的架构. 复制代码 代码如下: abstract class Abstrac

Flash/Flex学习笔记(28):动态文本的滚动控制

虽然label组件很好用,但是达人们都好象不太喜欢用组件(用组件后最明显的问题:会使swf文件增大好多),所以我也慢慢开始习惯能不用组件则尽量不用 import flash.events.Event; import flash.events.MouseEvent; var flag:int = 0; txtMsg.text = "这是一首很好听的歌:Going Home\nnot very often have we met \nbut the musics been too bad \ncan

Flash/Flex学习笔记(3):动态添加组件

Flash中一个fla文件可以关联到一个as文件,这个有点类似于asp.net中的code behind. 可参考以下图操作:     注:1.as文件的类名与文件名要求一样,并且默认情况下必须与fla处于同一目录.2.所有as文件必须继承自flash.display.Sprite 下面这个是一个示例文件代码: package { import flash.display.Sprite; import fl.controls.Label; import fl.controls.Button; i

Web Service学习笔记:动态调用WebService

原文:Web Service学习笔记:动态调用WebService 多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我们可能需要在程序运行期间动态调用一个未知的服务.在 .NET Framework 的 System.Web.Services.Description 命名空间中有我们需要的东西. 具体步骤: 1. 从目标 URL 下载 WSDL 数据. 2. 使用 ServiceDescription 创建和格式化 WSDL