`
devgis
  • 浏览: 140345 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

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();
}


分享到:
评论

相关推荐

    C#泛型、反射实例、自动生成sql语句

    在C#中,利用泛型和反射可以创建灵活的数据库操作库,自动根据实体类生成对应的SQL语句。例如,我们可以定义一个泛型方法,接受一个类型参数,这个类型对应于数据库表的实体模型: ```csharp public void Save(T ...

    C#,利用反射动态创建对象

    综上所述,C#的反射机制为开发者提供了在运行时动态操作代码的能力,尤其在处理不确定类型的对象或者需要实现动态行为时,反射成为了一种不可或缺的工具。然而,需要注意的是,由于其内在的性能成本,应当合理地在...

    如何用C#动态编译、执行代码

    这个类提供了对C#代码生成器和代码编译器实例的访问。如果想要动态生成Visual Basic代码,则可以使用`VBCodeProvider`类。 - **CreateCompiler()**:该方法用于获取编译器的实例。 #### ICodeCompiler 定义了一个...

    C#代码生成器(包括T-sql语句,和实体类代码)

    总结起来,"C#代码生成器(包括T-sql语句,和实体类代码)"是一个高效开发工具,它结合了反射、动态加载和代码生成等技术,帮助开发者快速生成T-SQL语句和实体类代码,降低了开发复杂性和维护成本。对于.NET开发者来...

    利用Type动态创建类实例(C#反射)可以演变抽象工厂

    在给定的标题“利用Type动态创建类实例(C#反射)可以演变抽象工厂”中,我们可以看到两个主要概念:Type和抽象工厂模式。下面将详细解释这两个知识点以及它们如何相互关联。 1. Type: C#中的Type类是System....

    C#代码自动生成

    总结来说,“C#代码自动生成”是通过反射和动态加载技术实现的,它可以自动处理实体类与数据库之间的映射,减少手动编码的繁琐工作。这种技术在大型项目中尤为有价值,因为它提高了开发效率,减少了错误,并且能适应...

    C#反射示例 动态生成方法

    本示例主要讲解如何使用C#反射来动态生成和执行方法,这对于构建高度可扩展和灵活的软件系统至关重要。 反射的核心在于`System.Reflection`命名空间中的类,如`Type`、`MethodInfo`、`ConstructorInfo`等。在我们的...

    C#反射生成SQL实例

    这个"C#反射生成SQL实例"可能包含一个具体的代码示例,展示了如何结合以上知识点来动态构建和执行SQL。通过学习这个实例,开发者可以更好地理解和应用C#反射在实际项目中的功能,提升代码的灵活性和可维护性。

    C# Model代码自动生成

    C# Model代码自动生成,可以自动根据类型生成对象函数。 public string DeptName { get { return deptName; } set { deptName = value; } }

    基于C#的代码自动生成器

    先配置bin文件夹下面的config.ini文件,ConnStr表示连接的数据库,运行本工具,选择对应的表,点击生成代码,程序会根据数据库里面表的配置信息和字段类型,名称等信息结合template文件夹下面的模板文件生成相关代码...

    .net c#动态创建程序集、类、属性、方法等

    总之,C#的动态创建程序集、类、属性和方法的能力为开发者提供了强大的工具,使得代码可以在运行时适应不断变化的需求,提高了程序的灵活性和可扩展性。然而,这种能力也需要谨慎使用,因为过度的动态代码可能会导致...

    C#自动生成.cs文件

    通过Razor语法,你可以混合HTML和C#代码来生成动态内容。 2. **代码生成库**: - **Roslyn**:微软的C#和VB.NET编译器平台,提供了API来分析、修改和生成C#代码。你可以使用Roslyn的编译器服务创建代码生成器,...

    c#中使用动态类的样例程序

    动态类是这种特性的体现,它允许我们在编译时无需知道全部细节的情况下创建和使用对象。以下是对"使用C#中动态类的样例程序"的详细说明。 1. **动态类型(dynamic)**: C# 4.0引入了`dynamic`关键字,它允许我们...

    c# 生成动态菜单 委托 事件 反射 递归 源代码

    在C#编程中,生成动态菜单是一项常见的任务,特别是在开发具有多层结构的用户界面时。这个主题涉及到了几个核心的编程概念:委托、事件、反射以及递归。接下来,我们将详细探讨这些知识点。 1. **委托(Delegate)*...

    C#代码动态编译、动态执行、动态调试[参照].pdf

    我们可以使用CodeCompileUnit来编译C#代码,生成动态代码。 在动态编译中,我们可以指定编译参数,例如:编译器的参数、引用文件等。使用CompilerParameters可以指定编译参数,例如:生成调试信息、引用文件等。 ...

    用Visual C#动态生成组件

    对于更高级的动态组件生成,可以使用`System.Reflection.Emit`命名空间,其中的`ILGenerator`类允许我们直接生成中间语言(IL)代码,而`DynamicMethod`则用于创建和执行这些IL代码,形成动态方法。 6. **动态类型...

    c#三层架构代码生成器

    Codematic 是一款为 C# 数据库程序员设计的自动代码生成器,Codematic 生成的代码基于基于面向对象的思想和三层架构设计,结合了Petshop中经典的思想和设计模式,融入了工厂模式,反射机制等等一些思想。采用 Model ...

    CreateClass_net c#动态创建程序集、类、属性、方法等

    在.NET框架中,C#语言提供了强大的元数据和反射机制,允许我们在运行时动态地创建、操作和执行程序集、类、属性以及方法。`CreateClass_net`项目就是利用这些特性来实现动态编程的一个示例。这篇内容将深入探讨如何...

    C#实体类生成工具

    在给定的“C#实体类生成工具”Demo中,我们可以看到一个简单的实现,它可能包含基础的数据库连接、查询表结构以及自动生成C#代码的功能。 首先,让我们了解实体类在软件开发中的作用。在面向对象编程中,实体类代表...

    C#代码生成器(开源)

    标题中的“C#代码生成器”是一个工具,它旨在自动化部分编程过程,特别是那些重复性较强的任务,例如创建业务逻辑层(BLL)、数据访问层(DAL)、SQL数据访问层(SqlIDAL)以及工厂模式(反射工厂)。这样的工具能够...

Global site tag (gtag.js) - Google Analytics