zoukankan      html  css  js  c++  java
  • C#动态方法调用 提高程序的扩展性

    此篇将介绍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.   
    20. /// <summary>  
    21. /// 该类独立放入Test.exe汇编  
    22. /// </summary>  
    23. class DynamicInvoke  
    24. {  
    25.     public static void Main(string[] args)  
    26.     {  
    27.         // 动态加载汇编  
    28.         string path = "Class1.dll";  
    29.         Assembly assembly = Assembly.Load(path);  
    30.   
    31.         // 根据类型名得到Type  
    32.         Type type = assembly.GetType("Class1");  
    33.   
    34.         // 1.根据方法名动态调用静态方法  
    35.         string str = (string)type.InvokeMember("method1", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, new object[] { });  
    36.         Console.WriteLine(str);  
    37.   
    38.         // 2.根据方法名动态调用动态对象的成员方法  
    39.         object o = Activator.CreateInstance(type);  
    40.         str = (string)type.InvokeMember("method2", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, new object[] { });  
    41.         Console.WriteLine(str);  
    42.   
    43.         // 3.根据方法名动态调用动态对象的有参成员方法  
    44.         object[] par = new object[] { "kunal" };  
    45.         str = (string)type.InvokeMember("method3", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, par);  
    46.         Console.WriteLine(str);  
    47.   
    48.         // 带out修饰的InvokeMember  
    49.         // System.Int32 中 public static bool TryParse(string s, out int result) 方法的调用  
    50.         var arguments = new object[] { str, null }; // 注意这里只能将参数写在外面,out参数为null也没有关系  
    51.         typeof(int).InvokeMember("TryParse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static,  
    52.              null, null, arguments);  
    53.         Console.WriteLine(arguments[1]);  
    54.     }  
    55. }</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.   
    9. namespace _32.DynamicReflection  
    10. {  
    11.     internal class Program  
    12.     {  
    13.         private static void Main(string[] args)  
    14.         {  
    15.             #region 内置标签方法 (动态加载)  
    16.   
    17.             const string className = "DynamicReflection.Test"; //类名称一定要全称  
    18.             string fileName = <strong>Thread.GetDomain().BaseDirectory + "Test.cs";</strong>  
    19.   
    20.             if (File.Exists(fileName))  
    21.             {  
    22.                 var sourceFile = new FileInfo(fileName);  
    23.                 CodeDomProvider provider = new CSharpCodeProvider();  
    24.                 var cp = new CompilerParameters();  
    25.                 cp.ReferencedAssemblies.Add("System.dll"); //添加命名空间引用    
    26.   
    27.                 cp.GenerateExecutable = false; // 生成类库   
    28.                 cp.GenerateInMemory = true; // 保存到内存   
    29.                 cp.TreatWarningsAsErrors = false; // 不将编译警告作为错误  
    30.   
    31.                 // 编译  
    32.                 CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceFile.FullName);  
    33.                 if (cr.Errors.Count < 1)  
    34.                 {  
    35.                     Assembly asm = cr.CompiledAssembly; // 加载   
    36.   
    37.                     //1.调用静态方法  
    38.                     Type type = asm.GetType(className);  
    39.                     var str =(string)type.InvokeMember("SayHello1", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, new object[] {});  
    40.                     Console.WriteLine(str);  
    41.   
    42.                     //2.调用实例方法  
    43.                     object instance = asm.CreateInstance(className);  
    44.                     str =(string)type.InvokeMember("SayHello2", BindingFlags.Default | BindingFlags.InvokeMethod, null, instance,new object[] {});  
    45.                     Console.WriteLine(str);  
    46.   
    47.                     //3.调用带参数的方法  
    48.                     var par = new object[] {"zhangqs008"};  
    49.                     str =(string)type.InvokeMember("SayHello3", BindingFlags.Default | BindingFlags.InvokeMethod, null, instance,par);  
    50.                     Console.WriteLine(str);  
    51.   
    52.                     Console.Read();  
    53.                 }  
    54.                 else  
    55.                 {  
    56.                     string msg = null;  
    57.                     for (int index = 0; index < cr.Errors.Count; index++)  
    58.                     {  
    59.                         CompilerError error = cr.Errors[index];  
    60.                         msg += "【错误" + (index + 1) + "】" + Environment.NewLine;  
    61.                         msg += "[文件] " + error.FileName + Environment.NewLine;  
    62.                         msg += "[位置] 行" + error.Line + ",列" + error.Column + Environment.NewLine;  
    63.                         msg += "[信息] " + error.ErrorText + Environment.NewLine;  
    64.                         msg += Environment.NewLine;  
    65.                     }  
    66.                     MessageBox.Show(msg, "内置方法类编译错误");  
    67.                 }  
    68.             }  
    69.  
    70.             #endregion  
    71.         }  
    72.     }  
    73. }</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.   
      10.         public string SayHello2()  
      11.         {  
      12.             return "hello instance method";  
      13.         }  
      14.   
      15.         public string SayHello3(string args)  
      16.         {  
      17.             return "hello args " + args;  
      18.         }  
      19.     }  
      20. }  
      21. </span> 
  • 相关阅读:
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Bound mismatch: The typae CertificateDirectory is not a valid substitute for the bounded parameter <M extends Serializable>
    Duplicate property mapping of contactPhone found in
  • 原文地址:https://www.cnblogs.com/shuzhengyi/p/4274317.html
Copyright © 2011-2022 走看看