C# 动态代码(反射和动态生成类)

  1. 一、反射的使用
  2. 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
  3. 需要使用的命名空间:System.Reflection
  4. 反射的作用很多,下面的例子主要是看一下怎么动态的调用类中的方法。
  5. 例子类
  6. classReflTest1
  7. {
  8. privatestring_prop1;
  9. publicstringProp1
  10. {
  11. get{return_prop1; }
  12. set{ _prop1 = value; }
  13. }
  14. publicvoidWrite1(stringstrText)
  15. {
  16. Console.WriteLine("111111111:"+ strText);
  17. }
  18. publicvoidWrite2(stringstrText)
  19. {
  20. Console.WriteLine("222222222:"+ strText);
  21. }
  22. publicvoidMyWrite(stringstrText)
  23. {
  24. Console.WriteLine("3333333333:"+ strText);
  25. }
  26. }
  27. 这个例子中提供了三个方法和一个属性,下面的代码来动态的调用它们:
  28. stringstrText ="abcd";
  29. BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public |
  30. BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
  31. Type t =typeof(ReflTest1);
  32. MethodInfo[] mi = t.GetMethods(flags);
  33. Object obj = Activator.CreateInstance(t);
  34. foreach(MethodInfo minmi)
  35. {
  36. if(m.Name.StartsWith("Write"))
  37. {
  38. m.Invoke(obj,newobject[] { strText });
  39. }
  40. }
  41. MethodInfo mMy = t.GetMethod("MyWrite");
  42. if(mMy !=null)
  43. {
  44. mMy.Invoke(obj,newobject[] { strText });
  45. }
  46. BindingFlags用来设置要取得哪些类型的方法,然后我们就可以取得这些方法来动态的调用。(当然为了可以循环的调用方法,在方法的命名方面可以自己指定一个规则)
  47. 二、动态生成类
  48. 我们可以在程序运行过程中调用.NET中提供的编译类,动态的将一段string编译成一个类,然后再通过反射来调用它
  49. 需要使用的命名空间:System.CodeDom System.CodeDom.Compiler Microsoft.CSharp System.Reflection
  50. 动态创建、编译类的代码如下:
  51. publicstaticAssembly NewAssembly()
  52. {
  53. //创建编译器实例。
  54. provider =newCSharpCodeProvider();
  55. //设置编译参数。
  56. paras =newCompilerParameters();
  57. paras.GenerateExecutable =false;
  58. paras.GenerateInMemory =true;
  59. //创建动态代码。
  60. StringBuilder classSource =newStringBuilder();
  61. classSource.Append("public class DynamicClass \n");
  62. classSource.Append("{\n");
  63. //创建属性。
  64. classSource.Append(propertyString("aaa"));
  65. classSource.Append(propertyString("bbb"));
  66. classSource.Append(propertyString("ccc"));
  67. classSource.Append("}");
  68. System.Diagnostics.Debug.WriteLine(classSource.ToString());
  69. //编译代码。
  70. CompilerResults result = provider.CompileAssemblyFromSource(paras, classSource.ToString());
  71. //获取编译后的程序集。
  72. Assembly assembly = result.CompiledAssembly;
  73. returnassembly;
  74. }
  75. privatestaticstringpropertyString(stringpropertyName)
  76. {
  77. StringBuilder sbProperty =newStringBuilder();
  78. sbProperty.Append(" private int _"+ propertyName +" = 0;\n");
  79. sbProperty.Append(" public int "+""+ propertyName +"\n");
  80. sbProperty.Append(" {\n");
  81. sbProperty.Append(" get{ return _"+ propertyName +";} \n");
  82. sbProperty.Append(" set{ _"+ propertyName +" = value; }\n");
  83. sbProperty.Append(" }");
  84. returnsbProperty.ToString();
  85. }propertyString方法就是用来拼写字符串的
  86. 整个代码比较简单,主要步骤就是:1、拼写类的字符串 2、调用CSharpCodeProvider类进行编译得到程序集(assembly)
  87. 接下来就可以利用之前反射的方法来动态调用这个类中的属性了:
  88. Assembly assembly = NewAssembly();
  89. objectClass1 = assembly.CreateInstance("DynamicClass");
  90. ReflectionSetProperty(Class1,"aaa", 10);
  91. ReflectionGetProperty(Class1,"aaa");
  92. objectClass2 = assembly.CreateInstance("DynamicClass");
  93. ReflectionSetProperty(Class1,"bbb", 20);
  94. ReflectionGetProperty(Class1,"bbb");
  95. DynamicClass是我动态类的类名,aaa和bbb是其中的属性
  96. ReflectionSetProperty和ReflectionGetProperty代码如下:
  97. 给属性赋值
  98. privatestaticvoidReflectionSetProperty(objectobjClass,stringpropertyName,intvalue)
  99. {
  100. PropertyInfo[] infos = objClass.GetType().GetProperties();
  101. foreach(PropertyInfo infoininfos)
  102. {
  103. if(info.Name == propertyName && info.CanWrite)
  104. {
  105. info.SetValue(objClass, value,null);
  106. }
  107. }
  108. }
  109. 取得属性的值
  110. privatestaticvoidReflectionGetProperty(objectobjClass,stringpropertyName)
  111. {
  112. PropertyInfo[] infos = objClass.GetType().GetProperties();
  113. foreach(PropertyInfo infoininfos)
  114. {
  115. if(info.Name == propertyName && info.CanRead)
  116. {
  117. System.Console.WriteLine(info.GetValue(objClass,null));
  118. }
  119. }
  120. }
C#代码
  1. <SPAN id=comment_body_1095076class=blog_comment_body>属性的赋值应该可以这样写:
  2. PropertyInfo _Property = objClass.GetType().GetProperty(propertyName);
  3. if(_Property !=null&& _Property.CanRead)
  4. {
  5. _Property.SetValue(objClass, value,null);
  6. }
  7. 取得应该可以这样写:
  8. PropertyInfo _Property = objClass.GetType().GetProperty(propertyName);
  9. if(_Property !=null&& _Property.CanWrite)
  10. {
  11. _Property.GetValue(objClass,null);
  12. }
  13. </SPAN>




/*
* 使用C#动态编译代码和执行
* 作者: yaob
*/
static void Main(string[] args)
{
//编译
CodeDomProvider cdp = CodeDomProvider.CreateProvider("C#");
//编译器的参数
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("System.dll");
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
//编译结果
CompilerResults cr = cdp.CompileAssemblyFromSource(cp, HelloWorld());
if (cr.Errors.HasErrors) Console.WriteLine("编译出错!");
else
{
//编译后的程序集
Assembly ass = cr.CompiledAssembly;
// 得到HelloWorld类中的SayHello方法
Type type = ass.GetType("HelloWorld.HelloWorld");
MethodInfo mi = type.GetMethod("SayHello");
// 执行
mi.Invoke(null, null);
}
}
//动态构建的代码
static string HelloWorld()
{
StringBuilder sbCode = new StringBuilder();
sbCode.AppendLine("using System;");
sbCode.AppendLine("namespace HelloWorld");
sbCode.AppendLine("{");
sbCode.AppendLine(" class HelloWorld");
sbCode.AppendLine(" {");
sbCode.AppendLine(" public static void SayHello()");
sbCode.AppendLine(" {");
sbCode.AppendLine(" Console.WriteLine(\"Hello~ World~!\");");
sbCode.AppendLine(" }");
sbCode.AppendLine(" }");
sbCode.AppendLine("}");
return sbCode.ToString();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值