C#通过反射获取类中的方法和参数个数,反射调用方法带参数

using System;
using System.Reflection;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            //反射获取 命名空间+类名
            string className = "ConsoleApp2.ClassSample";
            string methodName = "test1";
            //传递参数
            Object[] paras = new Object[] { "我的", "电脑" };
            var t = Type.GetType(className);
            object obj = Activator.CreateInstance(t);

            try
            {
                #region 方法一
                //直接调用
                MethodInfo method = t.GetMethod("test2");
                method.Invoke(obj, paras);
                #endregion

                #region 方法二
                MethodInfo[] info = t.GetMethods();
                for (int i = 0; i < info.Length; i++)
                {
                    var md = info[i];
                    //方法名
                    string mothodName = md.Name;
                    //参数集合
                    ParameterInfo[] paramInfos = md.GetParameters();
                    //方法名相同且参数个数一样
                    if (mothodName == methodName && paramInfos.Length == paras.Length)
                    {
                        md.Invoke(obj, paras);
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                throw ex;
            }
            Console.ReadKey();
        }
    }

    class ClassSample
    {
        public void test1(string para1)
        {
            Console.WriteLine("方式1 {0}________test111", para1);
        }

        public void test1(string para1, string para2)
        {
            Console.WriteLine("方式2 {0}________test111________{1}", para1, para2);
        }

        public void test2(string para1, string para2)
        {
            Console.WriteLine("方式3 {0}________test222________{1}", para1, para2);
        }
    }
}

在C#中,我们要使用反射,首先要搞清楚以下命名空间中几个类的关系:

System.Reflection命名空间

(1) AppDomain:应用程序域,可以将其理解为一组程序集的逻辑容器

(2) Assembly:程序集类

(3) Module:模块类

(4) Type:使用反射得到类型信息的最核心的类

他们之间是一种从属关系,也就是说,一个AppDomain可以包含N个Assembly,一个Assembly可以包含N个Module,而一个Module可以包含N个Type.

在程序中,如果我们要动态加载一个程序集有以下种方式可以使用,分别是LoadLoadFromLoadFileLoadWithPartialName方法.

其中着重讲解以下Assembly.LoadFileAssembly.LoadFrom的区别

1、Assembly.LoadFile只载入相应的dll文件,比如Assembly.LoadFile("abc.dll"),则载入abc.dll,假如abc.dll中引用了def.dll的话,def.dll并不会被载入。

Assembly.LoadFrom则不一样,它会载入dll文件及其引用的其他dll,比如上面的例子,def.dll也会被载入。

2、用Assembly.LoadFrom载入一个Assembly时,会先检查前面是否已经载入过相同名字的Assembly,比如abc.dll有两个版本(版本1在目录1下,版本2放在目录2下),程序一开始时载入了版本1,当使用Assembly.LoadFrom("2\\abc.dll")载入版本2时,不能载入,而是返回版本1。Assembly.LoadFile的话则不会做这样的检查,比如上面的例子换成Assembly.LoadFile的话,则能正确载入版本2。

LoadFile:加载指定路径上的程序集文件的内容。LoadFrom: 根据程序集的文件名加载程序集文件的内容。

最后是调用方法

Assembly outerAsm = Assembly.LoadFrom(@"urPath\MyDLL.dll");

调用DLL类中的方法

Type type = outerAsm .GetType("MyDLL.MyClass");//调用类型
MethodInfo method = type.GetMethod("MyVoid");//调用方法
//如果需要传参数

object[] paramertors = new object[] { "3087", "2005" };//参数集合
object test = method.Invoke(null, paramertors);//Invoke调用方法

调用DLL中窗体

Type outerForm = outerAsm.GetType("MyForm", false);//找到指定窗口
(Activator.CreateInstance(outerForm) as Form).Show();//转换成窗体类,显示

你可能感兴趣的:(.NET,c#,string,class)