代码改变世界

【转】C#动态方法调用

2011-12-18 11:15  cnb_mtime  阅读(1118)  评论(0编辑  收藏  举报

【转】C#动态方法调用

 1 上一篇《C# 运行时动态对象创建》介绍了C#如何在运行时动态的创建对象,包括泛型对象的一些方法。此篇将介绍C#如何在运行时动态调用方法。当某些类型是运行时动态确定时,编译时的静态编码是无法解决这些动态对象或类的方法调用的。此篇则给你一把利剑,让动态对象的方法调用成为可能。
2
3 /// <summary>
4 /// 该类将被独立编入Class1.dll汇编
5 /// </summary>
6 class Class1
7 {
8 public static string method1()
9 {
10 return "I am Static method (method1) in class1";
11 }
12 public string method2()
13 {
14 return "I am a Instance Method (method2) in Class1";
15 }
16 public string method3(string s)
17 {
18 return "Hello " + s;
19 }
20 }
21
22 /// <summary>
23 /// 该类独立放入Test.exe汇编
24 /// </summary>
25 class DynamicInvoke
26 {
27 public static void Main(string[] args)
28 {
29 // 动态加载汇编
30 string path = "Class1.dll";
31 Assembly assembly = Assembly.Load(path);
32
33 // 根据类型名得到Type
34 Type type = assembly.GetType("Class1");
35
36 // 根据方法名动态调用静态方法
37 string str = (string)type.InvokeMember("method1", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, new object[] { });
38 Console.WriteLine(str);
39
40 // 根据类型动态创建对象
41 object o = Activator.CreateInstance(type);
42
43 // 根据方法名动态调用动态对象的成员方法
44 str = (string)type.InvokeMember("method2", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, new object[] { });
45 Console.WriteLine(str);
46
47 // 根据方法名动态调用动态对象的有参成员方法
48 object[] par = new object[] { "kunal" };
49 str = (string)type.InvokeMember("method3", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, par);
50 Console.WriteLine(str);
51
52 // 带out修饰的InvokeMember
53 // System.Int32 中 public static bool TryParse(string s, out int result) 方法的调用
54 var arguments = new object[] { str, null}; // 注意这里只能将参数写在外面,out参数为null也没有关系
55 typeof(int).InvokeMember("TryParse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static,
56 null, null, arguments);
57 Console.WriteLine(arguments[1]);
58 }
59 }
.Net中的反射功能是极其强大的,本篇先用他来动态调用方法
看如下一个类
Public Class A
{
     public void InvokeMethod(string methodname)
    {
           Type p=this.GetType();
           MethodInfo m=p.GetMethod(methodname);
           if(m!=null)
              m.Invkoe(this,new object[0])
     }
     public void MethodA()
    {
    }
   
     public void MethodB()
    {
    }
}
上面的类中在InvokeMethod方法中传进MethodA或MethodB字符串就能执行MethodA或MethodB方法了
当然还可以在进行如下改进:
   public object FunctionA(int par1,object par2)
{
    do something...
    return some
}
 public object InvokeMethod(string methodname,object[] paramet)
{
           Type[] ptype=new Type[paramet.Length];
            for(int i=0;i<ptype.Length;i++)
                ptype[i]=paramet[i].GetType();
           Type p=this.GetType();
           MethodInfo m=p.GetMethod(methodname,ptype);
           if(m!=null)
              return m.Invkoe(this,paramet);
           return null
}
调用InvokeMethod并传进方法名称和方法参数就能调用相应的方法,并返回值.