知识大全 动态代码的使用(反射和动态生成类)
Posted 知
篇首语:博观而约取,厚积而薄发。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 动态代码的使用(反射和动态生成类)相关的知识,希望对你有一定的参考价值。
在软件开发尤其是框架和底层开发时 为了更灵活的控制代码 常常需要进行一些动态的操作 比如根据用户的输入等动态的调用类中的方法或者根据数据库表结构 用户要求动态的生成一些类 然后再动态的调用类中的方法 当然使用这些方式时会对性能有一点影响 具体使用过程中可以根据实际情况来定 不过一般的B/S开发中主要的瓶颈还是在数据库操作和网速方面 这点影响应该可以忽略的
一 反射的使用 可以使用反射动态地创建类型的实例 将类型绑定到现有对象 或从现有对象中获取类型 然后 可以调用类型的方法或访问其字段和属性 需要使用的命名空间 System Reflection 反射的作用很多 下面的例子主要是看一下怎么动态的调用类中的方法 例子类 class ReflTest private string _prop ;
public string Prop get return _prop ; set _prop = value;
public void Write (string strText) Console WriteLine(\\ :\\ + strText); public void Write (string strText) Console WriteLine(\\ :\\ + strText); public void MyWrite(string strText) Console WriteLine(\\ :\\ + strText); 这个例子中提供了三个方法和一个属性 下面的代码来动态的调用它们 string strText = \\ abcd\\ ;
BindingFlags flags = (BindingFlags NonPublic | BindingFlags Public | BindingFlags Static | BindingFlags Instance | BindingFlags DeclaredOnly);
Type t = typeof(ReflTest ); MethodInfo[] mi = t GetMethods(flags); Object obj = Activator CreateInstance(t);
foreach (MethodInfo m in mi) if (m Name StartsWith(\\ Write\\ )) m Invoke(obj new object[] strText ); [Page]
MethodInfo mMy = t GetMethod(\\ MyWrite\\ ); if (mMy != null) mMy Invoke(obj new object[] strText ); BindingFlags用来设置要取得哪些类型的方法 然后我们就可以取得这些方法来动态的调用 (当然为了可以循环的调用方法 在方法的命名方面可以自己指定一个规则)
二 动态生成类 我们可以在程序运行过程中调用 NET中提供的编译类 动态的将一段string编译成一个类 然后再通过反射来调用它 需要使用的命名空间 System CodeDom System CodeDom Compiler Microsoft CSharp System Reflection
动态创建 编译类的代码如下 public static Assembly NewAssembly() //创建编译器实例 provider = new CSharpCodeProvider(); //设置编译参数 paras = new CompilerParameters(); paras GenerateExecutable = false; paras GenerateInMemory = true;
//创建动态代码 StringBuilder classSource = new StringBuilder(); classSource Append(\\ public class DynamicClass \\\\n\\ ); classSource Append(\\ \\\\n\\ );
//创建属性 classSource Append(propertyString(\\ aaa\\ )); classSource Append(propertyString(\\ bbb\\ )); classSource Append(propertyString(\\ ccc\\ ));
classSource Append(\\ \\ );
System Diagnostics Debug WriteLine(classSource ToString());
//编译代码 CompilerResults result = provider CompileAssemblyFromSource(paras classSource ToString());
//获取编译后的程序集 Assembly assembly = result CompiledAssembly; [Page]
return assembly;
private static string propertyString(string propertyName) StringBuilder sbProperty = new StringBuilder(); sbProperty Append(\\ private int _\\ + propertyName + \\ = ;\\\\n\\ ); sbProperty Append(\\ public int \\ + \\ \\ + propertyName + \\ \\\\n\\ ); sbProperty Append(\\ \\\\n\\ ); sbProperty Append(\\ get return _\\ + propertyName + \\ ; \\\\n\\ ); sbProperty Append(\\ set _\\ + propertyName + \\ = value; \\\\n\\ ); sbProperty Append(\\ \\ ); return sbProperty ToString(); propertyString方法就是用来拼写字符串的 整个代码比较简单 主要步骤就是 拼写类的字符串 调用CSharpCodeProvider类进行编译得到程序集(assembly)
接下来就可以利用之前反射的方法来动态调用这个类中的属性了 Assembly assembly = NewAssembly();
object Class = assembly CreateInstance(\\ DynamicClass\\ ); ReflectionSetProperty(Class \\ aaa\\ ); ReflectionGetProperty(Class \\ aaa\\ );
cha138/Article/program/net/201311/13126相关参考