C#反射

而接下来要讲的另一个内容——反射,也能很好地帮助我们处理某些特殊的情况。

一、反射的概念:

反射提供了封装程序集、模块和类型的对象(Type类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用反射对它们进行访问。

一般使用:工厂类,通过反射创建类的实例,实现层与层之间的解耦:  数据层→数据会话层→业务逻辑层。 其中,数据会话层通过反射创建数据层的实例,业务逻辑层调用。

二、反射Type中的四个函数:

Person person = new Person();
            Student student = new Student();
            //判断指定的两个成员是否存在继承关系(判断一个类是否可用赋值给另一个类)    --后者继承于前者
            bool b1 = typeof(Person).IsAssignableFrom(typeof(Student));    //student继承了person
            bool b3 = person.GetType().IsAssignableFrom(student.GetType());//另一种写法
            bool b2 = typeof(Itest).IsAssignableFrom(typeof(Teacher));

            //判断是否是指定类的实例
            bool b4 = typeof(Person).IsInstanceOfType(student);     //结果为true   student继承了person
            bool b5 = person.GetType().IsInstanceOfType(student);//另一种写法   GetType当前对象的实例

            //判断是否是某个类的子类,非接口
            bool b6 = typeof(Student).IsSubclassOf(typeof(Person));

            //判断是否是抽象
            if (typeof(Drive).IsAbstract)
            {
                Console.WriteLine("是抽象的");
            }
            else
            {
                Console.WriteLine("不是抽象的");
            }
            Console.ReadKey();

1、把xxx.dll放到该应用程序的bin/Debug目录下或项目引用

string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"xxxx.dll");
Assembly ass = Assembly.LoadFile(path);  //需要绝对路径  LoadFile加载路径程序集内容        -->也不一定要在debug目录下,自己构建绝对路径也可
Type[] types = ass.GetTypes();             //获得加载到的程序集中的所有数据类型,包括公开和不公开的    
//Type[] types = ass.GetExportedTypes();   //获取加载到的公开程序集中的数据

2、可以遍历程序集中的类型,获取类型的命名空间和类型名称

foreach (Type item in types)
{ 
    Console.WriteLine(item.Name);             //类型名称  --也就是common下类或者接口的名称
    Console.WriteLine(item.Namespace);        //命名空间
}

3、获取指定程序集中的数据类型

//获得指定程序集中数据类型,包括公开的和不公开的
            Type type = ass.GetType("Common.FileCommon");
            Console.WriteLine(type.Name);
            Console.WriteLine(type.Namespace);

4、创建type对象

      a:创建没有构造函数的对象

object o = ass.CreateInstance("Common.FileCommon");     //FileCommom为Common命名空间的一个类 → 命名空间.类名 

  b:反射出来的类型有构造函数

object o2 = Activator.CreateInstance(type, "参数");

注意: 当反射出来的类型如果有构造函数,用上面代码中 ass.CreateInstance则会出现错误,如果有构造函数,那么该如何知道构造函数的参数?

ConstructorInfo [] info = type.GetConstructors();    //查询所有的构造函数,可以看到构造函数需要传递参数的参数类型

5、获得数据类型中所有的属性

//获得数据类型中所有的属性
            PropertyInfo[] pinfo = type.GetProperties();   //获取属性  然后可以遍历
            foreach (PropertyInfo item in pinfo)
            {
                Console.WriteLine(item.Name);
            }

6、获得数据类型中所有的函数

//获得数据类型中所有的方法函数
            MethodInfo[] minfo = type.GetMethods();   //获取所有的函数
            foreach (MethodInfo item in minfo)
            {
                Console.WriteLine(item.Name);
            }

7、目的:调用函数

 //调用WriteData函数
            MethodInfo method = type.GetMethod("WriteData");    //该类中的writeData方法
            object o3 = method.Invoke(o2, new object[] { "2.txt", "通过反射调用哒" });
            Console.WriteLine("调用成功");
            Console.ReadKey();

四、小结: 

当获得一个 .dll程序集的时候,需要先获取所有的类型,也就是这个程序集中的类,然后根据所需要类的名称,去创建指定名称的对象,如:Type type = ass.GetType("Common.FileCommon");  ,然后利用type获取构造函数、所有函数、属性(还有一些可以 type.方法名来获取相应的需求),再选择创建type对象的方法(构造或无构造),然后根据获得的函数来调用,传入相应的参数。

posted @ 2020-08-12 14:32  博客萌新  阅读(124)  评论(0编辑  收藏  举报