C#動態方法調用 提升程序的擴展性

此篇將介紹C#如何在運行時動態調用方法。當某些類型是運行時動態肯定時,編譯時的靜態編碼是沒法解決這些動態對象或類的方法調用的。此篇則給你一把利劍,讓動態對象的方法調用成爲可能。ide

1.動態調用dll裏的方法
編碼

[csharp] view plain copy print ?
  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.動態加載類文件並調用方法:spa

 

[csharp] view plain copy print ?
  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>  

類文件:.net

 

[csharp] view plain copy print ?
    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> 
相關文章
相關標籤/搜索