|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
java比较简单,没有C++的烦琐,但学习时最好有C++为基础.与JSP和SQL起应用,功能强大.
静态天生一个类关于AOP,O/RMapping等手艺十分有匡助。关于Java来讲,成绩不年夜,而关于.NET,则要贫苦些(次要贫苦在于完成代码的天生必要IL),故推测这大概也是在AOP,O/RMapping方面,Java走得略前的缘故原由吧。
贫苦回贫苦,非不克不及也,静态天生一个复杂的类还不至于太难。
假定有以下接口:
interfaceIAnimal
{
voidmove();
voideat();
}
但愿能创立一个类天生器TypeCreator,并能以以下体例利用:
TypeCreatortc=newTypeCreator(typeof(IAnimal));
Typet=tc.build();
IAnimalmyAnimal=(IAnimal)Activator.CreateInstance(t);
myAnimal.move();
myAnimal.eat();
起首,发明System.Reflection.Emit.TypeBuilder仿佛就是一个现成的类天生器。不外TypeBuilder既没有有用的static办法,也不克不及在内部实例化。不外ModuleBuilder倒有一个DefineType()办法,能够失掉TypeBuilder;而ModuleBuilder和TyperBuilder一个品德,不克不及间接创立,得从AssemblyBuilder的DefineDynamicModule()办法失掉。追根溯源,AssemblyBuilder得从AppDomain的DefineDynamicAssembly()的得来。终极幸亏AppDomain供应了一个静态办法:AppDomain.CurrentDomain.这连续串并不是没有事理,范例是依靠于Module的,而Module依靠于Assembly,而Assembly则被AppDomain装载。所谓“皮之不存,毛将焉附”,为了创立Type这个“毛”,得先把Assembly,Module这些“皮”顺次机关出来:
usingSystem;
usingSystem.Reflection;
usingSystem.Reflection.Emit;
publicclassTypeCreator
{
privateTypetargetType;
///<summary>
///机关函数
///</summary>
///<paramname="targetType">被完成大概承继的范例</param>
publicTypeCreator(TypetargetType)
{
this.targetType=targetType;
}
publicTypebuild()
{
//猎取以后AppDomain
AppDomaincurrentAppDomain=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("Im"+targetMethod.Name+"ing");}
ilGen.Emit(OpCodes.Ldstr,"Im"+targetMethod.Name+"ing");
ilGen.Emit(OpCodes.Call,typeof(Console).GetMethod("WriteLine",newType[]{typeof(String)}));
ilGen.Emit(OpCodes.Ret);
}
}
//真正创立,并前往
return(typeBuilder.CreateType());
}
}
<p>
专门做了这个例子;而java的这个例子好像就是为了教学而写的,很多教学目的的例子是不考虑优化、性能的。 |
|