C#動態方法調用
阿新 • • 發佈:2019-01-24
soft important vat con pan lse () sun 靜態
此篇將介紹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 class1View Code"; } 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.動態加載類文件並調用方法:
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 } } }
類文件:
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; } } }
C#動態方法調用