当前位置: 首页 > news >正文

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 操作系统篇--八股文学习第十二天| 什么是死锁,如何避免死锁?,介绍一下几种典型的锁,讲一讲你理解的虚拟内存
  • Typescript配置文件(tsconfig.json)详解系列五:allowArbitraryExtensions
  • PointNet点云语义分割
  • 使用Apache http client发送json数据(demo)
  • 02:【stm32】工程模板的创建
  • 考研英语二--小作文如何写
  • 苹果iPhone 16 Pro系列有望支持Wi-Fi 7,再也不说苹果信号不好了
  • Python | Leetcode Python题解之第315题计算右侧小于当前元素的个数
  • 08.02_111期_Linux_NAT技术
  • Binder、 AIDL 、IPC 大展神威
  • linux进程控制——进程等待——wait、waitpid
  • uniapp自定义网格布局用于选择金额、输入框焦点事件以及点击逻辑实战
  • 【面试题】C++:面向对象的三大特性?
  • Cocos Creator文档学习记录
  • Java二十三种设计模式-外观模式(9/23)
  • @jsonView过滤属性
  • 【comparator, comparable】小总结
  • 2017 前端面试准备 - 收藏集 - 掘金
  • 5、React组件事件详解
  • CentOS6 编译安装 redis-3.2.3
  • JSDuck 与 AngularJS 融合技巧
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • Mithril.js 入门介绍
  • mysql中InnoDB引擎中页的概念
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • 多线程事务回滚
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 聊一聊前端的监控
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 如何在 Tornado 中实现 Middleware
  • 算法-插入排序
  • 一、python与pycharm的安装
  • - 转 Ext2.0 form使用实例
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • 大数据全解:定义、价值及挑战
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​Linux·i2c驱动架构​
  • ​如何防止网络攻击?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • # SpringBoot 如何让指定的Bean先加载
  • #HarmonyOS:Web组件的使用
  • #Linux(权限管理)
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • ()、[]、{}、(())、[[]]命令替换
  • (1)Nginx简介和安装教程
  • (26)4.7 字符函数和字符串函数
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • (Python) SOAP Web Service (HTTP POST)
  • (web自动化测试+python)1
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (四)图像的%2线性拉伸
  • (一)认识微服务
  • (一)为什么要选择C++
  • (游戏设计草稿) 《外卖员模拟器》 (3D 科幻 角色扮演 开放世界 AI VR)