C#动态⽅法调⽤
此篇将介绍C#如何在运⾏时动态调⽤⽅法。当某些类型是运⾏时动态确定时,编译时的静态编码是⽆法解决这些动态对象或类的⽅法调⽤的。此篇则给你⼀把利剑,让动态对象的⽅法调⽤成为可能。
1.动态调⽤dll⾥的⽅法:
<span >/// <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>
/
// 该类独⽴放⼊汇编
/// </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 >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>
类⽂件:
DynamicReflection
{
public class Test
{
public static string SayHello1()
{
return "hello static method";
}
public string SayHello2()
{
return "hello instance method";
}writeline方法的作用
public string SayHello3(string args)
{
return "hello args " + args;
}
}
}