代码生成器:动态代码的使用(反射和动态生成类)来源: 发布时间:星期四, 2009年2月12日 浏览:463次 评论:0
在软件Software开发尤其是框架和底层开发时为了更灵活控制代码常常需要进行些动态操作比如根据用户输入等动态类中思路方法或者根据数据库表结 构、用户要求动态生成些类然后再动态类中思路方法当然使用这些方式时会对性能有点影响具体使用过程中可以根据实际情况来定不过般 B/S开发中主要瓶颈还是在数据库操作和网速方面这点影响应该可以忽略 、反射使用 可以使用反射动态地创建类型例子将类型绑定到现有对象或从现有对象中获取类型然后可以类型思路方法或访问其字段和属性 需要使用命名空间:.Reflection 反射作用很多下面例子主要是看下如何动态类中思路方法 例子类 ReflTest1 { private_prop1; publicProp1 { get{_prop1;} {_prop1=value;} } publicvoidWrite1(strText) { Console.WriteLine("111111111:"+strText); } publicvoidWrite2(strText) { Console.WriteLine("222222222:"+strText); } publicvoidMyWrite(strText) { Console.WriteLine("3333333333:"+strText); } } 这个例子中提供了 3个思路方法和个属性下面代码来动态它们: strText="abcd"; BindingFlagsflags=(BindingFlags.NonPublic|BindingFlags.Public| BindingFlags.Static|BindingFlags.Instance|BindingFlags.DeclaredOnly); Typet=typeof(ReflTest1); MethodInfomi=t.GetMethods(flags); Objectobj=Activator.CreateInstance(t); foreach(MethodInfominmi) { (m.Name.StartsWith("Write")) { m.Invoke(obj,object{strText}); }[Page] } MethodInfomMy=t.GetMethod("MyWrite"); (mMy!=null) { mMy.Invoke(obj,object{strText}); } BindingFlags用来设置要取得哪些类型思路方法然后我们就可以取得这些思路方法来动态(当然为了可以循环思路方法在思路方法命名方面可以自己指定个规则) 2、动态生成类 我们可以在运行过程中.NET中提供编译类动态将段编译成个类然后再通过反射来它 需要使用命名空间:.CodeDom .CodeDom.Compiler Microsoft.CSharp .Reflection 动态创建、编译类代码如下: publicAssemblyNewAssembly { //创建编译器例子 provider=CSharpCodeProvider; //设置编译参数 paras=CompilerParameters; paras.GenerateExecutable=false; paras.GenerateInMemory=true; //创建动态代码 StringBuilderSource=StringBuilder; Source.Append("publicDynamicClass\n"); Source.Append("{\n"); //创建属性 Source.Append(propertyString("aaa")); Source.Append(propertyString("bbb")); Source.Append(propertyString("ccc")); Source.Append("}"); .Diagnostics.Debug.WriteLine(Source.); //编译代码 CompilerResultsresult=provider.CompileAssemblyFromSource(paras,Source.); //获取编译后集 Assemblyassembly=result.CompiledAssembly;[Page] assembly; } privatepropertyString(propertyName) { StringBuildersbProperty=StringBuilder; sbProperty.Append("private_"+propertyName+"=0;\n"); sbProperty.Append("public"+""+propertyName+"\n"); sbProperty.Append("{\n"); sbProperty.Append("get{_"+propertyName+";}\n"); sbProperty.Append("{_"+propertyName+"=value;}\n"); sbProperty.Append("}"); sbProperty.; } propertyString思路方法就是用来拼写串 整个代码比较简单主要步骤就是:1、拼写类串 2、CSharpCodeProvider类进行编译得到集(assembly) 接下来就可以利用的前反射思路方法来动态这个类中属性了: Assemblyassembly=NewAssembly; objectClass1=assembly.CreateInstance("DynamicClass"); ReflectionSetProperty(Class1,"aaa",10); ReflectionGetProperty(Class1,"aaa"); objectClass2=assembly.CreateInstance("DynamicClass"); ReflectionSetProperty(Class1,"bbb",20); ReflectionGetProperty(Class1,"bbb"); DynamicClass是我动态类类名aaa和bbb是其中属性 ReflectionSetProperty和ReflectionGetProperty代码如下: 给属性赋值 privatevoidReflectionSetProperty(objectobjClass,propertyName,value) { PropertyInfoinfos=objClass.GetType.GetProperties; foreach(PropertyInfoinfoininfos) { (info.NamepropertyName&&info.CanWrite)[Page] { info.SetValue(objClass,value,null); } } } 取得属性值 privatevoidReflectionGetProperty(objectobjClass,propertyName) { PropertyInfoinfos=objClass.GetType.GetProperties; foreach(PropertyInfoinfoininfos) { (info.NamepropertyName&&info.CanRead) { .Console.WriteLine(info.GetValue(objClass,null)); } } } 3
相关文章读者评论发表评论 |