C#动态方法调用 提高程序的扩展性
此篇将介绍C#如何在运行时动态调用方法。当某些类型是运行时动态确定时,编译时的静态编码是无法解决这些动态对象或类的方法调用的。此篇则给你一把利剑,让动态对象的方法调用成为可能。
1.动态调用dll里的方法
- <span style="font-family:SimSun;font-size:12px;">/// <summary>
- /// 该类将被独立编入Class1.dll汇编
- /// </summary>
- class Class1
- {
- public static string method1()
- {
- return "I am Static method (method1) in class1";
- }
- public string method2()
- {
- return "I am a Instance Method (method2) in Class1";
- }
- public string method3(string s)
- {
- return "Hello " + s;
- }
- }
- /// <summary>
- /// 该类独立放入Test.exe汇编
- /// </summary>
- class DynamicInvoke
- {
- public static void Main(string[] args)
- {
- // 动态加载汇编
- string path = "Class1.dll";
- Assembly assembly = Assembly.Load(path);
- // 根据类型名得到Type
- Type type = assembly.GetType("Class1");
- // 1.根据方法名动态调用静态方法
- string str = (string)type.InvokeMember("method1", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, new object[] { });
- Console.WriteLine(str);
- // 2.根据方法名动态调用动态对象的成员方法
- object o = Activator.CreateInstance(type);
- str = (string)type.InvokeMember("method2", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, new object[] { });
- Console.WriteLine(str);
- // 3.根据方法名动态调用动态对象的有参成员方法
- object[] par = new object[] { "kunal" };
- str = (string)type.InvokeMember("method3", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, par);
- Console.WriteLine(str);
- // 带out修饰的InvokeMember
- // System.Int32 中 public static bool TryParse(string s, out int result) 方法的调用
- var arguments = new object[] { str, null }; // 注意这里只能将参数写在外面,out参数为null也没有关系
- typeof(int).InvokeMember("TryParse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static,
- null, null, arguments);
- Console.WriteLine(arguments[1]);
- }
- }</span>
2.动态加载类文件并调用方法:
- <span style="font-family:SimSun;font-size:12px;">using System;
- using System.CodeDom.Compiler;
- using System.IO;
- using System.Reflection;
- using System.Threading;
- using System.Windows.Forms;
- using Microsoft.CSharp;
- namespace _32.DynamicReflection
- {
- internal class Program
- {
- private static void Main(string[] args)
- {
- #region 内置标签方法 (动态加载)
- const string className = "DynamicReflection.Test"; //类名称一定要全称
- string fileName = <strong>Thread.GetDomain().BaseDirectory + "Test.cs";</strong>
- if (File.Exists(fileName))
- {
- var sourceFile = new FileInfo(fileName);
- CodeDomProvider provider = new CSharpCodeProvider();
- var cp = new CompilerParameters();
- cp.ReferencedAssemblies.Add("System.dll"); //添加命名空间引用
- cp.GenerateExecutable = false; // 生成类库
- cp.GenerateInMemory = true; // 保存到内存
- cp.TreatWarningsAsErrors = false; // 不将编译警告作为错误
- // 编译
- CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceFile.FullName);
- if (cr.Errors.Count < 1)
- {
- Assembly asm = cr.CompiledAssembly; // 加载
- //1.调用静态方法
- Type type = asm.GetType(className);
- var str =(string)type.InvokeMember("SayHello1", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, new object[] {});
- Console.WriteLine(str);
- //2.调用实例方法
- object instance = asm.CreateInstance(className);
- str =(string)type.InvokeMember("SayHello2", BindingFlags.Default | BindingFlags.InvokeMethod, null, instance,new object[] {});
- Console.WriteLine(str);
- //3.调用带参数的方法
- var par = new object[] {"zhangqs008"};
- str =(string)type.InvokeMember("SayHello3", BindingFlags.Default | BindingFlags.InvokeMethod, null, instance,par);
- Console.WriteLine(str);
- Console.Read();
- }
- else
- {
- string msg = null;
- for (int index = 0; index < cr.Errors.Count; index++)
- {
- CompilerError error = cr.Errors[index];
- msg += "【错误" + (index + 1) + "】" + Environment.NewLine;
- msg += "[文件] " + error.FileName + Environment.NewLine;
- msg += "[位置] 行" + error.Line + ",列" + error.Column + Environment.NewLine;
- msg += "[信息] " + error.ErrorText + Environment.NewLine;
- msg += Environment.NewLine;
- }
- MessageBox.Show(msg, "内置方法类编译错误");
- }
- }
- #endregion
- }
- }
- }</span>
类文件:
- <span style="font-family:SimSun;font-size:12px;">namespace DynamicReflection
- {
- public class Test
- {
- public static string SayHello1()
- {
- return "hello static method";
- }
- public string SayHello2()
- {
- return "hello instance method";
- }
- public string SayHello3(string args)
- {
- return "hello args " + args;
- }
- }
- }
- </span>
C#动态方法调用 提高程序的扩展性的更多相关文章
- struts2.3.15.3中动态方法调用默认是关闭的
初学ssh,用的struts2.3.15.3,使用了如下表单: <form action="/spring3/index/login.action" method=" ...
- 第三章Struts2 Action中动态方法调用、通配符的使用
01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问Servl ...
- Struts2 动态方法调用
01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问Servl ...
- Struts2学习第二天——动态方法调用
method属性 在前面的例子里,Action默认使用execute()方法来处理请求.但是,如果有多个不同的请求需要同一个Action进行不同处理,怎么办?在Struts.xml文件中,需要指定Ac ...
- JavaWeb_(Struts2框架)struts.xml核心配置、动态方法调用、结果集的处理
此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...
- Struts2学习笔记 - Action篇<动态方法调用>
有三种方法可以使一个Action处理多个请求 动态方法调用DMI 定义逻辑Acton 在配置文件中使用通配符 这里就说一下Dynamic Method nvocation ,动态方法调用,什么是动态方 ...
- struts之动态方法调用使用通配符
一.DMI动态方法调用的其中一种改变form表单中action属性的方式已经讲过了.还有两种,一种是改变struts.xml配置文件中action标签中的method属性,来指定执行不同的方法处理不同 ...
- struts之动态方法调用改变表单action属性
一.动态方法调用(DMI:Dynamic Method Invocation) ⒈struts2中同样提供了这个包含多个逻辑业处理的Action,这样就可以在一个Action中进行多个业务逻辑处理 ...
- struts2DMI(动态方法调用)
struts2动态方法调用共有三种方式: 1.通过action元素的method属性指定访问该action时运行的方法 <package name="action" exte ...
随机推荐
- 【bzoj1009】: [HNOI2008]GT考试 字符串-kmp-矩阵乘法-DP
[bzoj1009]: [HNOI2008]GT考试 先用kmp写个暴力 /* http://www.cnblogs.com/karl07/ */ #include <cstdlib> # ...
- 微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务
http://skaka.me/blog/2016/04/21/springcloud1/ 不同于单一架构应用(Monolith), 分布式环境下, 进行事务操作将变得困难, 因为分布式环境通常会有多 ...
- java开发系统内核:让内核从严重错误中恢复
更详细的讲解和代码调试演示过程,请参看视频 用java开发C语言编译器 更详细的讲解和代码调试演示过程,请参看视频 如何进入google,算法面试技能全面提升指南 如果你对机器学习感兴趣,请参看一下链 ...
- promise思考
我写了三个单元块,分别对应三种业务场景 let query;query = (url) => { url=url||"传递的参数为空"; return new Promise ...
- 基于linux内核包过滤技术的应用网关
目录 基于linux内核包过滤技术的应用网关 硬件形态 基本原理 应用场景 主要功能 其他功能 客户定制 基于linux内核包过滤技术的应用网关 硬件形态 基本原理 应用场景 媒体内容过滤和深度识别 ...
- rest-assured之静态导入及简单使用实例
一.静态导入 为了有效的使用rest-assured,官网推荐从下列class中静态导入方法: io.restassured.RestAssured.* io.restassured.matcher. ...
- P4331 [BOI2004]Sequence 数字序列 (左偏树)
[题目链接] https://www.luogu.org/problemnew/show/P4331 题目描述 给定一个整数序列\(a_1, a_2, ··· , a_n,\)求出一个递增序列\(b_ ...
- React笔记:ref注意事项
[一]使用ref必须用在[类型式的组件]才起作用,用在[函数式的组件]是无效的. 下面这个例子用在了[函数式的组件]上,所以是无效的: function MyFunctionalComponent() ...
- 洛谷 P3205 [HNOI2010]合唱队
题目链接 题解 区间dp \(f[i][j]\)表示i~j区间最后一次插入的是\(a[i]\) \(g[i][j]\)表示i~j区间最后一次插入的是\(a[j]\) 然后就是普通区间dp转移 Code ...
- BZOJ - 1257 分块 详解
中文题面 这道题就是LightOJ某题的升级版 前段时间我是直接用√k前暴力后分块的处理方式,然后直接套个等差求和 这次看到了dalao的证明再次让我知道我好菜啊 在这里做下笔记,学习一下对于整除运算 ...