C#根据反射操作对象

前言

反射使用,让我们的程序可以动态增加一些功能,让原本固化的步骤逻辑变得动态,这是它的优点。当然使用反射首次加载会有性能损耗以及使用复杂;但是现在大家都在讲动态,使用好它应该是一个重要的编程理念提升。MVC、ORM、IOC、AOPA都有使用这个东西了。如果要考虑性能,可以考虑缓存程序集,我们保证程序只加载一次就好。

一、直接利用反射读写对象的值

 static void Main(string[] args)
        {
            Person p = new Person() { Name = "丁竹", Age = 26, Sex = true };
            p.Working("readinof");

            //利用反射读取值
            object obj = p;
            var type = obj.GetType();
            foreach (var item in type.GetProperties())
            {
                string value = item.GetValue(obj, null).ToString();
                Console.WriteLine($"{item.Name} {value}");
            }

            Assembly ass = Assembly.Load("ReadInfo");
            object pObj = ass.CreateInstance("ReadInfo.Person");

            //利用反射设置值
            {
                System.Reflection.PropertyInfo propertyInfo = type.GetProperty("Name");
                propertyInfo.SetValue(obj, "ding", null);
            }
            Console.Read();
        }

二、通过反射调用实例

 static void Main(string[] args)
        {
            //[1].CsharpCodePrivode
            //提供对C#代码生成器和代码编译器的实例的访问。如果要动态生成VB代码,可以使用VBCodeProvider.
            //CreateCompiler():获取编译器的实例
            CSharpCodeProvider objcsharpcodeprivoder = new CSharpCodeProvider();

            //[2].ICodeComplier
            //定义用于调用源代码编译的接口或使用指定编译器的CodeDOM树。
            //每种编译方法都接受编译器的ComplierParameter对象,并返回指示编译结果的CompilerResults对象
            ICodeCompiler codeCompiler = objcsharpcodeprivoder.CreateCompiler();

            //[3].ComplierParameters 表示用于调用编译器的参数
            //ReferencedAssembies:获取当前项目所引用的程序集。Add方法为程序集添加引用
            //GenerateExecutable:获取或设置一个值,该值指示是否生成可执行文件。若此属性为false,则生成Dll,默认是false.
            //GenerateInMemor:获取或设置一个值,该值指示是否在内存中生成输出。
      
            CompilerParameters objcompilerparameters = new CompilerParameters();
           // objcompilerparameters.ReferencedAssemblies.Add("System.dll");
            objcompilerparameters.GenerateExecutable = false;
            objcompilerparameters.GenerateInMemory = true;

            //[4].CompilerResults 表示从编译器返回的编译结果
            //CompiedAssembly:获取或设置以编译的程序集,Assembly类型。

            CompilerResults cr = codeCompiler.CompileAssemblyFromSource(objcompilerparameters, GenerateCode());
            if (cr.Errors.HasErrors)
            {
                Console.WriteLine("编译错误:");
                foreach (CompilerError item in cr.Errors)
                {
                    Console.WriteLine(item.ErrorText);
                }
            }
            else
            {
                //通过反馈,调用HelloWorld实例
                Assembly assembly = cr.CompiledAssembly;
                object objHelloWorld = assembly.CreateInstance("DynamicCodeGenerate.HelloWorld");
                MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut");
                Console.WriteLine(objMI.Invoke(objHelloWorld,null));
            }
            Console.ReadLine();
        }
        static string GenerateCode()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("using System;");
            sb.Append(Environment.NewLine);
            sb.Append("namespace DynamicCodeGenerate");
            sb.Append(Environment.NewLine);
            sb.Append("{");
            sb.Append(Environment.NewLine);
            sb.Append(" public class HelloWorld");
            sb.Append(Environment.NewLine);
            sb.Append(" {");
            sb.Append(Environment.NewLine);
            sb.Append(" public string OutPut()");
            sb.Append(Environment.NewLine);
            sb.Append(" {");
            sb.Append(Environment.NewLine);
            sb.Append(" return \"Hello world!\";");
            sb.Append(Environment.NewLine);
            sb.Append(" }");
            sb.Append(Environment.NewLine);
            sb.Append(" }");
            sb.Append(Environment.NewLine);
            sb.Append(" }");
            string code = sb.ToString();
            Console.WriteLine(code);
            Console.WriteLine();
            return code;
        }

三、通过动态加载Dll生成实例

  dom.DoCompileFile(Path.Combine(pathStr, filename), "Test.dll");

            MySampleDomain = AppDomain.CreateDomain("MySampleDomain");

           ass = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + "Test.dll");
            obj = MySampleDomain.CreateInstanceAndUnwrap(ass.FullName, "Sample.Demo");

四、通过反射调用方法

  Type type = obj.GetType();
            MethodInfo method = type.GetMethod("Add");
           int a=Convert.ToInt32( method.Invoke(obj, new object[] { 1,3 }));
            Console.WriteLine(a);

五、完整代码

public class ReflexHelp
    {
        public void Execute(string gencode)
        {
            //[1].CsharpCodePrivode
            //提供对C#代码生成器和代码编译器的实例的访问。如果要动态生成VB代码,可以使用VBCodeProvider.
            //CreateCompiler():获取编译器的实例
            CSharpCodeProvider objcsharpcodeprivoder = new CSharpCodeProvider();

            //[2].ICodeComplier
            //定义用于调用源代码编译的接口或使用指定编译器的CodeDOM树。
            //每种编译方法都接受编译器的ComplierParameter对象,并返回指示编译结果的CompilerResults对象
            ICodeCompiler codeCompiler = objcsharpcodeprivoder.CreateCompiler();

            //[3].ComplierParameters 表示用于调用编译器的参数
            //ReferencedAssembies:获取当前项目所引用的程序集。Add方法为程序集添加引用
            //GenerateExecutable:获取或设置一个值,该值指示是否生成可执行文件。若此属性为false,则生成Dll,默认是false.
            //GenerateInMemor:获取或设置一个值,该值指示是否在内存中生成输出。

            CompilerParameters objcompilerparameters = new CompilerParameters();
            // objcompilerparameters.ReferencedAssemblies.Add("System.dll");
            objcompilerparameters.GenerateExecutable = false;
            objcompilerparameters.GenerateInMemory = true;

            //[4].CompilerResults 表示从编译器返回的编译结果
            //CompiedAssembly:获取或设置以编译的程序集,Assembly类型。

            CompilerResults cr = codeCompiler.CompileAssemblyFromSource(objcompilerparameters, gencode);
            if (cr.Errors.HasErrors)
            {
                Console.WriteLine("编译错误:");
                foreach (CompilerError item in cr.Errors)
                {
                    Console.WriteLine(item.ErrorText);
                }
            }
            else
            {
                //通过反馈,调用HelloWorld实例
                Assembly assembly = cr.CompiledAssembly;
                object objHelloWorld = assembly.CreateInstance("DynamicCodeGenerate.HelloWorld");
                MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut");
                Console.WriteLine(objMI.Invoke(objHelloWorld, null));
            }
        }

        public object GenObject(string dllFileName, string typeName)
        {
            Assembly ass = Assembly.LoadFile(dllFileName);

            return ass.CreateInstance(typeName);
        }

        public int GetAddInfo(object obj, string methrName)
        {
            Type type = obj.GetType();
            MethodInfo method = type.GetMethod(methrName);
            return Convert.ToInt32(method.Invoke(obj, new object[] { 1, 3 }));
        }

        /// <summary>
        /// 编译代码
        /// </summary>
        /// <param name="provider">编译器</param>
        /// <param name="sourceFile">源文件</param>
        /// <param name="gentenFile">生成文件名</param>
        /// <returns>编译结果</returns>
        public CompilerResults CompileCode(CodeDomProvider provider, string sourceFile, string gentenFile)
        {
            string[] referenceAssemblies = { "System.dll" };
            CompilerParameters cp = new CompilerParameters(referenceAssemblies, gentenFile, false);
            cp.GenerateExecutable = false;//设置是否要包含一个入口点
            CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceFile);
            return cr;
        }
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值