C#强化系列文章五:动态代码的使用(反射和动态生成类)

在软件开发尤其是框架和底层开发时,为了更灵活的控制代码,常常需要进行一些动态的操作。比如根据用户的输入等动态的调用类中的方法或者根据数据库表结构、用户要求动态的生成一些类,然后再动态的调用类中的方法。当然使用这些方式时会对性能有一点影响,具体使用过程中可以根据实际情况来定,不过一般的B/S开发中主要的瓶颈还是在数据库操作和网速方面,这点影响应该可以忽略的C#强化系列文章五:动态代码的使用(反射和动态生成类)
下面我就从这两个方面来说说动态代码的使用:
一、反射的使用
可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
需要使用的命名空间:System.Reflection
反射的作用很多,下面的例子主要是看一下怎么动态的调用类中的方法。
C#强化系列文章五:动态代码的使用(反射和动态生成类)例子类
这个例子中提供了三个方法和一个属性,下面的代码来动态的调用它们:
C#强化系列文章五:动态代码的使用(反射和动态生成类)            string strText = "abcd";
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            BindingFlags flags 
= (BindingFlags.NonPublic | BindingFlags.Public |
C#强化系列文章五:动态代码的使用(反射和动态生成类)                BindingFlags.Static 
| BindingFlags.Instance | BindingFlags.DeclaredOnly);
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            Type t 
= typeof(ReflTest1);
C#强化系列文章五:动态代码的使用(反射和动态生成类)            MethodInfo[] mi 
= t.GetMethods(flags);
C#强化系列文章五:动态代码的使用(反射和动态生成类)            Object obj 
= Activator.CreateInstance(t);
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
foreach (MethodInfo m in mi)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
{
C#强化系列文章五:动态代码的使用(反射和动态生成类)                
if (m.Name.StartsWith("Write"))
C#强化系列文章五:动态代码的使用(反射和动态生成类)                
{
C#强化系列文章五:动态代码的使用(反射和动态生成类)                    m.Invoke(obj, 
new object[] { strText });
C#强化系列文章五:动态代码的使用(反射和动态生成类)                }

C#强化系列文章五:动态代码的使用(反射和动态生成类)            }

C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            MethodInfo mMy 
= t.GetMethod("MyWrite");
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
if (mMy != null)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
{
C#强化系列文章五:动态代码的使用(反射和动态生成类)                mMy.Invoke(obj, 
new object[] { strText });
C#强化系列文章五:动态代码的使用(反射和动态生成类)            }

C#强化系列文章五:动态代码的使用(反射和动态生成类)
BindingFlags用来设置要取得哪些类型的方法,然后我们就可以取得这些方法来动态的调用。(当然为了可以循环的调用方法,在方法的命名方面可以自己指定一个规则)

二、动态生成类
我们可以在程序运行过程中调用.NET中提供的编译类,动态的将一段string编译成一个类,然后再通过反射来调用它
需要使用的命名空间:System.CodeDom System.CodeDom.Compiler Microsoft.CSharp System.Reflection
动态创建、编译类的代码如下:
C#强化系列文章五:动态代码的使用(反射和动态生成类)        public static Assembly NewAssembly()
C#强化系列文章五:动态代码的使用(反射和动态生成类)        
{
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
//创建编译器实例。   
C#强化系列文章五:动态代码的使用(反射和动态生成类)
            provider = new CSharpCodeProvider();
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
//设置编译参数。   
C#强化系列文章五:动态代码的使用(反射和动态生成类)
            paras = new CompilerParameters();
C#强化系列文章五:动态代码的使用(反射和动态生成类)            paras.GenerateExecutable 
= false;
C#强化系列文章五:动态代码的使用(反射和动态生成类)            paras.GenerateInMemory 
= true;
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
//创建动态代码。   
C#强化系列文章五:动态代码的使用(反射和动态生成类)
            StringBuilder classSource = new StringBuilder();
C#强化系列文章五:动态代码的使用(反射和动态生成类)            classSource.Append(
"public   class   DynamicClass \n");
C#强化系列文章五:动态代码的使用(反射和动态生成类)            classSource.Append(
"{\n");
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
//创建属性。   
C#强化系列文章五:动态代码的使用(反射和动态生成类)
            classSource.Append(propertyString("aaa"));
C#强化系列文章五:动态代码的使用(反射和动态生成类)            classSource.Append(propertyString(
"bbb"));
C#强化系列文章五:动态代码的使用(反射和动态生成类)            classSource.Append(propertyString(
"ccc"));
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            classSource.Append(
"}");
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            System.Diagnostics.Debug.WriteLine(classSource.ToString());
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
//编译代码。   
C#强化系列文章五:动态代码的使用(反射和动态生成类)
            CompilerResults result = provider.CompileAssemblyFromSource(paras, classSource.ToString());
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
//获取编译后的程序集。   
C#强化系列文章五:动态代码的使用(反射和动态生成类)
            Assembly assembly = result.CompiledAssembly;
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
return assembly;
C#强化系列文章五:动态代码的使用(反射和动态生成类)        }

C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)        
private static string propertyString(string propertyName)
C#强化系列文章五:动态代码的使用(反射和动态生成类)        
{
C#强化系列文章五:动态代码的使用(反射和动态生成类)            StringBuilder sbProperty 
= new StringBuilder();
C#强化系列文章五:动态代码的使用(反射和动态生成类)            sbProperty.Append(
" private   int   _" + propertyName + "   =   0;\n");
C#强化系列文章五:动态代码的使用(反射和动态生成类)            sbProperty.Append(
" public   int   " + "" + propertyName + "\n");
C#强化系列文章五:动态代码的使用(反射和动态生成类)            sbProperty.Append(
" {\n");
C#强化系列文章五:动态代码的使用(反射和动态生成类)            sbProperty.Append(
" get{   return   _" + propertyName + ";}   \n");
C#强化系列文章五:动态代码的使用(反射和动态生成类)            sbProperty.Append(
" set{   _" + propertyName + "   =   value;   }\n");
C#强化系列文章五:动态代码的使用(反射和动态生成类)            sbProperty.Append(
" }");
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
return sbProperty.ToString();
C#强化系列文章五:动态代码的使用(反射和动态生成类)        }
propertyString方法就是用来拼写字符串的
整个代码比较简单,主要步骤就是:1、拼写类的字符串  2、调用CSharpCodeProvider类进行编译得到程序集(assembly)

接下来就可以利用之前反射的方法来动态调用这个类中的属性了:
C#强化系列文章五:动态代码的使用(反射和动态生成类)            Assembly assembly = NewAssembly();
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
object Class1 = assembly.CreateInstance("DynamicClass");
C#强化系列文章五:动态代码的使用(反射和动态生成类)            ReflectionSetProperty(Class1, 
"aaa"10);
C#强化系列文章五:动态代码的使用(反射和动态生成类)            ReflectionGetProperty(Class1, 
"aaa");
C#强化系列文章五:动态代码的使用(反射和动态生成类)
C#强化系列文章五:动态代码的使用(反射和动态生成类)            
object Class2 = assembly.CreateInstance("DynamicClass");
C#强化系列文章五:动态代码的使用(反射和动态生成类)            ReflectionSetProperty(Class1, 
"bbb"20);
C#强化系列文章五:动态代码的使用(反射和动态生成类)            ReflectionGetProperty(Class1, 
"bbb");
DynamicClass是我动态类的类名,aaa和bbb是其中的属性
ReflectionSetProperty和ReflectionGetProperty代码如下:
C#强化系列文章五:动态代码的使用(反射和动态生成类)给属性赋值

C#强化系列文章五:动态代码的使用(反射和动态生成类)取得属性的值




    本文转自永春博客园博客,原文链接:http://www.cnblogs.com/firstyi/archive/2008/03/07/1094652.html,如需转载请自行联系原作者


上一篇:IPFS助力元宇宙底层建设,FIL随之高涨!


下一篇:Silverlight实用窍门系列:9.动态生成实体类,根据XML模板使用Emit生成动态类绑定到DataGrid【附代实例源码】