.NET-18-反射中Type类的使用

Type类使用来执行反射的主要类型之一

Type在反射中有什么的操作方法

如下为部分使用方式

class Program
    {
        static void Main(string[] args)
        {
            //反射只能操作程序集(C#)或者包(java),这是因为他们编译之后是IL中间语言,所以能通过反射获取到对应的信息
            //但是C++编写的程序在编译之后就已经是机器码,所以C++的dll是不能使用反射来进行操作的

            #region   Type类能做什么

            ////获取一个对象的type的方式有两种
            ////1.直接创建一个对象,根据对象获取
            //MyClass m = new MyClass();
            //Type yp1 = m.GetType();

            ////直接获取,不需要创建类的对象
            //Type tp2 = typeof(MyClass);

            ////1.获取父类的信息
            //Console.WriteLine(tp2.BaseType.ToString());//父类
            ////Console.WriteLine(tp2.BaseType.BaseType.ToString());//父类的父类

            ////2.获取该类中所有的字段信息
            ////这里只能获取非私有的字段
            //FieldInfo[] fields = tp2.GetFields();
            //for (int i = 0; i < fields.Length; i++)
            //{
            //    Console.WriteLine(fields[i].Name);
            //}

            ////3.获取所有的属性信息
            //PropertyInfo[] prpys = tp2.GetProperties();
            //for (int i = 0; i < prpys.Length; i++)
            //{
            //    Console.WriteLine(prpys[i].Name);
            //}

            ////4.获取所有成员
            //MemberInfo[] mis = tp2.GetMembers();
            //for (int i = 0; i < mis.Length; i++)
            //{
            //    Console.WriteLine(mis[i].Name);
            //}

            ////5.获取所有方法
            //MethodInfo[] mtis = tp2.GetMethods();
            //for (int i = 0; i < mtis.Length; i++)
            //{
            //    Console.WriteLine(mtis[i].Name);
            //}


            //6.获取私有成员
            Type typesy = typeof(MyClass);
            //这个只能调用共有的方法,调用私有的成员会报错
            //应为这里SayHi是私有的,会找不到
            //MethodInfo methodsy = typesy.GetMethod("SayHi");
            //使用他的重载
            MethodInfo methodsy = typesy.GetMethod("SayHi", BindingFlags.NonPublic | BindingFlags.Instance);
            methodsy.Invoke(Activator.CreateInstance(typesy), null);

            //Console.ReadKey();
            #endregion   Type类能做什么

            //动态加载程序集并且调用
            //1.根据dll文件的路径,动态加载程序集
            Assembly asm = Assembly.LoadFile(@"C:\Users\Administrator\Desktop\test\NET基础加强\反射\TestDLL\bin\Debug\TestDLL.dll");

            //2.根据动态加载的程序集,获取程序集中的类型
            #region     获取程序集中的类型
            //2.1获取所有类型
            Type[] types = asm.GetTypes();
            //输出一下
            for (int i = 0; i < types.Length; i++)
            {
                Console.WriteLine("{0}\\{1}", types[i].FullName, types[i].Name);
            }
            Console.WriteLine("---------------------------------------------------------");

            //2.2获取所有的Public类型
            Type[] types2 = asm.GetExportedTypes();
            //输出一下
            for (int i = 0; i < types2.Length; i++)
            {
                Console.WriteLine("{0}\\{1}", types2[i].FullName, types2[i].Name);
            }
            Console.WriteLine("---------------------------------------------------------");

            //2.3获取指定的类型,获取Persong类型
            Type typePerson = asm.GetType("TestDLL.Person");
            Console.WriteLine(typePerson.FullName);
            Console.WriteLine("---------------------------------------------------------");
            ////获取参数的类型
            //Type mm = typePerson.GetMethod("SayHello").GetParameters()[0].ParameterType;

            #endregion    获取程序集中的类型

            //3.调用获取到类型的方法
            #region     调用获取到类型的方法

            //获取指定的类型Person
            Type perType = asm.GetType("TestDLL.Person");
            //根据已经获取的类型获取指定的方法
            MethodInfo meth = perType.GetMethod("SayHello");
            //根据指定的type(类型),创建Person的对象
            object obj = Activator.CreateInstance(perType);
            //调用指定的方法
            meth.Invoke(obj, null);
            Console.WriteLine("---------------------------------------------------------");

            //多个重载方法的调用,调用重载就是通过后面的Type数组来区分
            //调用无参的重载方法,如果是多个重载,后面一个参数不能省略,否则会出现匹配不明确错误
            MethodInfo mtehwc = perType.GetMethod("SayHi", new Type[] { });
            mtehwc.Invoke(Activator.CreateInstance(perType), null);
            Console.WriteLine("---------------------------------------------------------");

            //调用有参的重载方法
            MethodInfo mtehyc = perType.GetMethod("SayHi", new Type[] { typeof(string), typeof(string) });
            mtehyc.Invoke(Activator.CreateInstance(perType), new object[] { "新增", "测试" });
            Console.WriteLine("---------------------------------------------------------");

            //调用有返回值得方法,Invoke是有返回值得,直接接收到的就是有返回值的方法的返回值
            MethodInfo mtehfh = perType.GetMethod("Add", new Type[] { typeof(int), typeof(int) });
            int r = (int)mtehfh.Invoke(Activator.CreateInstance(perType), new object[] { 10, 20 });
            Console.WriteLine(r);
            Console.WriteLine("---------------------------------------------------------");
            #endregion   调用获取到类型的方法

            //通过Type创建一个对象
            #region    通过Type创建一个Person对象

            Type personType = asm.GetType("TestDLL.Person");
            //创建一个Person对象
            //这里只能调用无参的构造函数,如果是有参的构造函数,则无法指定
            object person1 = Activator.CreateInstance(personType);

            //如果想要指定有参数的构造函数,则可以使用下面的方式
            //通过调用指定的构造函数来创建Person对象
            ConstructorInfo cuInfo = personType.GetConstructor(new Type[] { typeof(string), typeof(int) });
            //调用构造函数来创建对象
            object person2 = cuInfo.Invoke(new object[] { "盈盈", 18 });

            //通过反射确定调用之后的值是否正确
            PropertyInfo prperInfo = personType.GetProperty("Name");
            //传入构造函数创建的对象,第二个参数索引器不需要,所以传null
            string name = prperInfo.GetValue(person2, null).ToString();
            Console.WriteLine(name);
            Console.WriteLine("---------------------------------------------------------");
            #endregion    通过Type创建一个Person对象


            #region     Type类操作
            //使用IsAssignableFrom来判断是否可以把对象赋值给另一个对象
            Type persoType = typeof(Person);
            Type teatherType = typeof(Teather);
            Type studentType = typeof(Student);

            //表示检查能否将teatherType的对象赋值给persoType的对象
            bool b = persoType.IsAssignableFrom(teatherType);//自身可以赋值
            Console.WriteLine(b);
            bool b1 = persoType.IsAssignableFrom(teatherType);//父子类关系也可以赋值
            Console.WriteLine(b1);
            bool b2 = persoType.IsAssignableFrom(studentType);
            Console.WriteLine(b2);
            bool b3 = teatherType.IsAssignableFrom(studentType);
            Console.WriteLine(b3);
            Console.WriteLine("---------------------------------------------------------");


            //使用IsInstanceOfType检查某个对象是否是某个类型
            object objPersong = Activator.CreateInstance(persoType);
            object objTeacher = Activator.CreateInstance(teatherType);
            object objStudent = Activator.CreateInstance(studentType);

            Console.WriteLine(persoType.IsInstanceOfType(objPersong));
            Console.WriteLine(persoType.IsInstanceOfType(objTeacher));//如果是父子关系也可以进行赋值
            Console.WriteLine(persoType.IsInstanceOfType(objStudent));//如果是父子关系也可以进行赋值
            Console.WriteLine(studentType.IsInstanceOfType(teatherType));
            Console.WriteLine("---------------------------------------------------------");

            //IsSubclassOf判断是否是父子类关系
            //这里只能验证父子类关系,和接口的实现没有关系
            Console.WriteLine(studentType.IsSubclassOf(persoType));
            Console.WriteLine(teatherType.IsSubclassOf(persoType));
            Console.WriteLine(persoType.IsSubclassOf(persoType));
            Console.WriteLine(studentType.IsSubclassOf(teatherType));
            Console.WriteLine("---------------------------------------------------------");


            //验证是否是抽象的,不能被实例化的
            //只要不能被实例化都会被认为是抽象的,包括接口,抽象类,静态类
            Type ifly = typeof(IFlyable);
            Console.WriteLine(persoType.IsAbstract);
            Console.WriteLine(studentType.IsAbstract);
            Console.WriteLine(teatherType.IsAbstract);
            Console.WriteLine(ifly.IsAbstract);
            Console.WriteLine("---------------------------------------------------------");

            #endregion    Type类操作

            Console.ReadKey();
        }
    }

    /// <summary>
    /// 创建一个类
    /// </summary>
    public class MyClass
    {
        private string _name;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private int _age;

        public int Age
        {
            get { return _age; }
            set { _age = value; }
        }

        public void Say()
        {
            Console.WriteLine("嗨");
        }

        private void SayHi()
        {
            Console.WriteLine("这是个私有的成员");
        }
    }


    public class Person
    {

    }

    public class Teather : Person
    {

    }

    public class Student : Person
    {

    }

    public interface IFlyable
    {

    }

猜你喜欢

转载自blog.csdn.net/m0_37532448/article/details/81331123