专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »DotNet » 代码生成器:动态代码的使用(反射和动态生成类) »正文

代码生成器:动态代码的使用(反射和动态生成类)

来源: 发布时间:星期四, 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

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: