此篇将介绍C#如何在运行时动态调用方法。当某些类型是运行时动态确定时,编译时的静态编码是无法解决这些动态对象或类的方法调用的。此篇则给你一把利剑,让动态对象的方法调用成为可能。

1.动态调用dll里的方法

  1. <span style="font-family:SimSun;font-size:12px;">/// <summary>
  2. /// 该类将被独立编入Class1.dll汇编
  3. /// </summary>
  4. class Class1
  5. {
  6. public static string method1()
  7. {
  8. return "I am Static method (method1) in class1";
  9. }
  10. public string method2()
  11. {
  12. return "I am a Instance Method (method2) in Class1";
  13. }
  14. public string method3(string s)
  15. {
  16. return "Hello " + s;
  17. }
  18. }
  19. /// <summary>
  20. /// 该类独立放入Test.exe汇编
  21. /// </summary>
  22. class DynamicInvoke
  23. {
  24. public static void Main(string[] args)
  25. {
  26. // 动态加载汇编
  27. string path = "Class1.dll";
  28. Assembly assembly = Assembly.Load(path);
  29. // 根据类型名得到Type
  30. Type type = assembly.GetType("Class1");
  31. // 1.根据方法名动态调用静态方法
  32. string str = (string)type.InvokeMember("method1", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, new object[] { });
  33. Console.WriteLine(str);
  34. // 2.根据方法名动态调用动态对象的成员方法
  35. object o = Activator.CreateInstance(type);
  36. str = (string)type.InvokeMember("method2", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, new object[] { });
  37. Console.WriteLine(str);
  38. // 3.根据方法名动态调用动态对象的有参成员方法
  39. object[] par = new object[] { "kunal" };
  40. str = (string)type.InvokeMember("method3", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, par);
  41. Console.WriteLine(str);
  42. // 带out修饰的InvokeMember
  43. // System.Int32 中 public static bool TryParse(string s, out int result) 方法的调用
  44. var arguments = new object[] { str, null }; // 注意这里只能将参数写在外面,out参数为null也没有关系
  45. typeof(int).InvokeMember("TryParse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static,
  46. null, null, arguments);
  47. Console.WriteLine(arguments[1]);
  48. }
  49. }</span>

2.动态加载类文件并调用方法:

  1. <span style="font-family:SimSun;font-size:12px;">using System;
  2. using System.CodeDom.Compiler;
  3. using System.IO;
  4. using System.Reflection;
  5. using System.Threading;
  6. using System.Windows.Forms;
  7. using Microsoft.CSharp;
  8. namespace _32.DynamicReflection
  9. {
  10. internal class Program
  11. {
  12. private static void Main(string[] args)
  13. {
  14. #region 内置标签方法 (动态加载)
  15. const string className = "DynamicReflection.Test"; //类名称一定要全称
  16. string fileName = <strong>Thread.GetDomain().BaseDirectory + "Test.cs";</strong>
  17. if (File.Exists(fileName))
  18. {
  19. var sourceFile = new FileInfo(fileName);
  20. CodeDomProvider provider = new CSharpCodeProvider();
  21. var cp = new CompilerParameters();
  22. cp.ReferencedAssemblies.Add("System.dll"); //添加命名空间引用
  23. cp.GenerateExecutable = false; // 生成类库
  24. cp.GenerateInMemory = true; // 保存到内存
  25. cp.TreatWarningsAsErrors = false; // 不将编译警告作为错误
  26. // 编译
  27. CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceFile.FullName);
  28. if (cr.Errors.Count < 1)
  29. {
  30. Assembly asm = cr.CompiledAssembly; // 加载
  31. //1.调用静态方法
  32. Type type = asm.GetType(className);
  33. var str =(string)type.InvokeMember("SayHello1", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, new object[] {});
  34. Console.WriteLine(str);
  35. //2.调用实例方法
  36. object instance = asm.CreateInstance(className);
  37. str =(string)type.InvokeMember("SayHello2", BindingFlags.Default | BindingFlags.InvokeMethod, null, instance,new object[] {});
  38. Console.WriteLine(str);
  39. //3.调用带参数的方法
  40. var par = new object[] {"zhangqs008"};
  41. str =(string)type.InvokeMember("SayHello3", BindingFlags.Default | BindingFlags.InvokeMethod, null, instance,par);
  42. Console.WriteLine(str);
  43. Console.Read();
  44. }
  45. else
  46. {
  47. string msg = null;
  48. for (int index = 0; index < cr.Errors.Count; index++)
  49. {
  50. CompilerError error = cr.Errors[index];
  51. msg += "【错误" + (index + 1) + "】" + Environment.NewLine;
  52. msg += "[文件] " + error.FileName + Environment.NewLine;
  53. msg += "[位置] 行" + error.Line + ",列" + error.Column + Environment.NewLine;
  54. msg += "[信息] " + error.ErrorText + Environment.NewLine;
  55. msg += Environment.NewLine;
  56. }
  57. MessageBox.Show(msg, "内置方法类编译错误");
  58. }
  59. }
  60. #endregion
  61. }
  62. }
  63. }</span>

类文件:

    1. <span style="font-family:SimSun;font-size:12px;">namespace DynamicReflection
    2. {
    3. public class Test
    4. {
    5. public static string SayHello1()
    6. {
    7. return "hello static method";
    8. }
    9. public string SayHello2()
    10. {
    11. return "hello instance method";
    12. }
    13. public string SayHello3(string args)
    14. {
    15. return "hello args " + args;
    16. }
    17. }
    18. }
    19. </span>

C#动态方法调用 提高程序的扩展性的更多相关文章

  1. struts2.3.15.3中动态方法调用默认是关闭的

    初学ssh,用的struts2.3.15.3,使用了如下表单: <form action="/spring3/index/login.action" method=" ...

  2. 第三章Struts2 Action中动态方法调用、通配符的使用

    01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问Servl ...

  3. Struts2 动态方法调用

    01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问Servl ...

  4. Struts2学习第二天——动态方法调用

    method属性 在前面的例子里,Action默认使用execute()方法来处理请求.但是,如果有多个不同的请求需要同一个Action进行不同处理,怎么办?在Struts.xml文件中,需要指定Ac ...

  5. JavaWeb_(Struts2框架)struts.xml核心配置、动态方法调用、结果集的处理

    此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...

  6. Struts2学习笔记 - Action篇<动态方法调用>

    有三种方法可以使一个Action处理多个请求 动态方法调用DMI 定义逻辑Acton 在配置文件中使用通配符 这里就说一下Dynamic Method nvocation ,动态方法调用,什么是动态方 ...

  7. struts之动态方法调用使用通配符

    一.DMI动态方法调用的其中一种改变form表单中action属性的方式已经讲过了.还有两种,一种是改变struts.xml配置文件中action标签中的method属性,来指定执行不同的方法处理不同 ...

  8. struts之动态方法调用改变表单action属性

      一.动态方法调用(DMI:Dynamic Method Invocation) ⒈struts2中同样提供了这个包含多个逻辑业处理的Action,这样就可以在一个Action中进行多个业务逻辑处理 ...

  9. struts2DMI(动态方法调用)

    struts2动态方法调用共有三种方式: 1.通过action元素的method属性指定访问该action时运行的方法 <package name="action" exte ...

随机推荐

  1. pycharm设置连接

    https://blog.csdn.net/u013088062/article/details/50100121

  2. MySQL5.7配置(第一次使用)

    MySQL5.7配置(第一次使用) 最近因为工作需要学习mysql的增删改查.用的公司的电脑,之前有人已经安装过mysql5.7,等于使用了免安装版,重新开始配置.参考了以下文章 http://blo ...

  3. ob系列函数归纳

     输出控制函数(output control函数) flush — 刷新输出缓冲ob_clean — 清空(擦掉)输出缓冲区ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲ob_end_ ...

  4. jmeter 正则表达式的关联

    在工作中,用JM录制了登录---退出的脚本,但是多次请求后发现,总是返回的录制脚本的时候使用的账号的数据. 经过研究发现,login后,响应里的每次返回的token值是变化的,顺着往下看,下一个请求中 ...

  5. _.each _.map _.filter javascript 语法

    1.forEach():没有返回值,只是针对每个元素调用func     简单来说,就是将数组中的每个值,依次进行遍历,执行功能函数     如果只需对数组元素进行操作,不需返回任何值时适用 var ...

  6. angularjs指令弹框点击空白处隐藏及常规方法

    效果图展示: 第一种方法:angularjs自定义指令: 指令: app.directive('onBlankHide', function () { return { restrict: 'A', ...

  7. apache shiro学习笔记

    一.权限概述 1.1 认证与授权 认证:系统提供的用于识别用户身份的功能,通常登录功能就是认证功能-----让系统知道你是谁?? 授权:系统授予用户可以访问哪些功能的许可(证书)----让系统知道你能 ...

  8. UVA - 11388 唯一分解定理

    题意:给出G和L,求最小的a使得gcd(a,b)=G,lcm(a,b)=L 显然a>=G,所以a取G,b要满足质因子质数为L的同次数,b取L //此处应有代码

  9. vue实现进入页面表单聚焦

    <input type="text" ref="input"/> <script> mounted(){ this.$refs['inp ...

  10. [转] Spring Boot配置多个DataSource

    [From]  https://www.liaoxuefeng.com/article/001484212576147b1f07dc0ab9147a1a97662a0bd270c20000 Sprin ...