zoukankan      html  css  js  c++  java
  • 反射调用方法

    首先准备一个要操作的类,有以下几个方法

    public class Test
    {
        public void Show()
        {
            Console.WriteLine("hello");
        }
        public void Show(string name)
        {
            Console.WriteLine($"hello {name}");
        }
        public void ShowGeneric<T>()
        {
            Console.WriteLine($"ShowGeneric,T:{typeof(T)}");
        }
        public void ShowGeneric2<T>()
        {
            Console.WriteLine($"ShowGeneric2,T:{typeof(T)}");
        }
        public void ShowGeneric2<T>(string name)
        {
            Console.WriteLine($"ShowGeneric2 hello {name},T:{typeof(T)}");
        }
        public void ShowGeneric2<T>(string name,T t)
        {
            Console.WriteLine($"ShowGeneric2 hello {name},T:{t.GetType()}");
        }
        public void ShowGeneric2<T, K>(int a)
        {
            Console.WriteLine($"T:{typeof(T)},K:{typeof(K)},a:{a}");
        }
    }

    首先获取该类的Type,创建一个实例,相当于 Test t=New T();

    Type type = typeof(Test);
    Object obj = Activator.CreateInstance(type);

    之后通过GetMethod方法获取要调用的方,第一个参数是方法名,第二个参数是方法的参数列表的Type数组。一般情况下可以省略,在这个例子中Show方法有重载,所以要加上第二个参数以指定调用哪个方法。就算没有参数也要写new Type[] { }。最后通过Invoke调用方法,第一个参数是第一步创建的实例,第二个参数是方法的参数,是Object数组,没有则为null。

    MethodInfo m = type.GetMethod("Show", new Type[] { });
    m.Invoke(obj, null);

    下面是一个带参数的方法

    MethodInfo m = type.GetMethod("Show", new Type[] { typeof(string) });
    m.Invoke(obj, new object[] { "jack" });

    接下来是泛型方法,MakeGenericMethod(typeof(string))指定了泛型的类型相当于t.ShowGeneric<String>()

    MethodInfo m = type.GetMethod("ShowGeneric");
    MethodInfo m2 = m.MakeGenericMethod(typeof(string));
    m2.Invoke(obj, null);

    然后是重载泛型方法的调用,对于参数列表里不包含泛型参数的方法的调用跟普通的方法是一样,而如果其中有泛型的参数的话就要用另一种方法了。

    MethodInfo m = type.GetMethod("ShowGeneric2",new Type[] { });
    MethodInfo m2 = m.MakeGenericMethod(typeof(string));
    m2.Invoke(obj, null);
    
    MethodInfo m2 = type.GetMethod("ShowGeneric2", new Type[] {typeof(string) });
    MethodInfo m3 = m2.MakeGenericMethod(typeof(string));
    m3.Invoke(obj, new object[] { "jack" });

    下面是一个参数列表中包含泛型类型的方法的调用,首先获取Test类中所有的方法,然后根据方法名,方法的泛型,方法的参数列表这些条件来获取到要调用的方法。

    MethodInfo m = type.GetMethods().FirstOrDefault(t => {
        var a = t.GetGenericArguments();//获取方法的泛型参数,返回类型是Type[]
        var p = t.GetParameters();//获取方法的参数列表,返回类型是ParameterInfo[]
        return t.Name == "ShowGeneric2" && a.Length == 1 && p.Length == 2 && p[0].ParameterType == typeof(string) && p[1].ParameterType == a[0];
    });
    MethodInfo m2 = m.MakeGenericMethod(typeof(string));
    m2.Invoke(obj, new object[] { "jack","jack" });

    除此之外还有一个方法可以获取方法,就是直接将方法ToString()后比对,这种方法有个小问题是参数列表的类型,string会变成 System.String,而Int会变成Int32,一会有Sytem一会没有,搞不懂是根据什么来的。用这种方法最好先看下输出一个结果再写判断条件。

    MethodInfo m = type.GetMethod("Show", new Type[] { });m.Invoke(obj, null);

  • 相关阅读:
    数据库系统原理:范式理论
    数据库系统原理:MVCC
    数据库系统原理:悲观锁、乐观锁
    数据库系统原理:封锁
    数据库系统原理:四大隔离级别
    数据库系统原理:ACID的作用以及实现原理
    计算机网络HTTP:长连接与短连接
    计算机网络HTTP:HTTP缓存
    计算机网络HTTP:状态码
    yum安装Docker
  • 原文地址:https://www.cnblogs.com/zhouyg2017/p/12728766.html
Copyright © 2011-2022 走看看