`
wyf
  • 浏览: 433474 次
  • 性别: Icon_minigender_1
  • 来自: 唐山
社区版块
存档分类
最新评论

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

阅读更多
一、反射的使用
可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
需要使用的命名空间:System.Reflection
反射的作用很多,下面的例子主要是看一下怎么动态的调用类中的方法。
例子类
    class ReflTest1
    {
        private string _prop1;

        public string Prop1
        {
            get { return _prop1; }
            set { _prop1 = value; }
        }
    
        public void Write1(string strText)
        {
            Console.WriteLine("111111111:" + strText);
        }
        public void Write2(string strText)
        {
            Console.WriteLine("222222222:" + strText);
        }
        public void MyWrite(string strText)
        {
            Console.WriteLine("3333333333:" + strText);
        }
    }
这个例子中提供了三个方法和一个属性,下面的代码来动态的调用它们:
            string strText = "abcd";

            BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public |
                BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);

            Type t = typeof(ReflTest1);
            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 });
                }
            }

            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;

            return assembly;
        }

        private static string propertyString(string propertyName)
        {
            StringBuilder sbProperty = new StringBuilder();
            sbProperty.Append(" private   int   _" + propertyName + "   =   0;\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方法就是用来拼写字符串的
整个代码比较简单,主要步骤就是:1、拼写类的字符串  2、调用CSharpCodeProvider类进行编译得到程序集(assembly)

接下来就可以利用之前反射的方法来动态调用这个类中的属性了:
            Assembly assembly = NewAssembly();

            object Class1 = assembly.CreateInstance("DynamicClass");
            ReflectionSetProperty(Class1, "aaa", 10);
            ReflectionGetProperty(Class1, "aaa");

            object Class2 = assembly.CreateInstance("DynamicClass");
            ReflectionSetProperty(Class1, "bbb", 20);
            ReflectionGetProperty(Class1, "bbb");
DynamicClass是我动态类的类名,aaa和bbb是其中的属性
ReflectionSetProperty和ReflectionGetProperty代码如下:
给属性赋值
        private static void ReflectionSetProperty(object objClass, string propertyName, int value)
        {
            PropertyInfo[] infos = objClass.GetType().GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if (info.Name == propertyName && info.CanWrite)
                {
                    info.SetValue(objClass, value, null);
                }
            }
        }
取得属性的值
        private static void ReflectionGetProperty(object objClass, string propertyName)
        {
            PropertyInfo[] infos = objClass.GetType().GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if (info.Name == propertyName && info.CanRead)
                {
                    System.Console.WriteLine(info.GetValue(objClass, null));
                }
            }
        }
属性的赋值应该可以这样写: 
PropertyInfo _Property = objClass.GetType().GetProperty(propertyName); 
if (_Property != null && _Property.CanRead) 
{ 
_Property.SetValue(objClass, value, null); 
} 

取得应该可以这样写: 
PropertyInfo _Property = objClass.GetType().GetProperty(propertyName); 
if (_Property != null && _Property.CanWrite) 
{ 
_Property.GetValue(objClass, null); 
} 

 

分享到:
评论

相关推荐

    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#反射在实际项目中的功能,提升代码的灵活性和可维护性。

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

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

    C# Model代码自动生成

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

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

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

    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 ...

    C#利用反射动态编译代码,创建类的实例,并调用其成员[文].pdf

    本文将通过一个经典实例,介绍C#中的反射机制,并说明如何使用反射来动态生成代码,创建类的实例,并调用其成员。 反射机制 在.NET Framework中,反射(Reflection)是一种高级功能,它允许开发者在运行时inspect...

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

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

    C#代码生成器(开源)

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

Global site tag (gtag.js) - Google Analytics