C#中的反射关键类-Type

在C#中,存在程序集的概念,程序集就是我们所写的一个代码集合,经编译器编译后得到的供进一步编译执行的产物,某个代码库(.dll)文件或是某个可执行文件(.exe)都是程序集。对于程序的类,类内函数与变量等就是程序的元数据,元数据就是描述数据的数据,它被保存在程序集中。一个运行中的程序可以查看其他程序集或自身程序集的元数据,这个行为就叫做反射,通过反射,不仅可以得到程序集中的的信息,也可以对它们进行实例化,执行与操作。

C#中,Type类就是反射功能最基础的类,也称为类的信息类。通过它,我们可以访问元数据,获取有关类型声明的信息,也可以获取有关类型的成员

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

namespace lesson20
{
    class Test 
    {
        private int i = 1;
        public int j = 0;
        public string str = "123";

        public Test() { }

        public Test(int i) 
        {
            this.i = i;
        }

        public Test(int i, string str) : this(i) 
        {
            this.str = str;
        }
        

        public void Speak() 
        {
            Console.WriteLine(i);
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            #region Type类(类的信息类)
            //获取Type
            //1.利用GetType()获取元数据的类型信息
            int a = 42;
            Type type = a.GetType(); 
            Console.WriteLine(type);
            //2.利用typeof关键字获取获取元数据的类型信息
            Type type2 = typeof(int);
            Console.WriteLine(type2);
            //3.利用类名获取类型信息
            Type type3 = Type.GetType("System.Int32");
            Console.WriteLine(type3);
            //不同Type变量得到的同种Type都指向同样的堆内存,一种类型仅有唯一的Type
            Console.WriteLine("****************************************************");
            //得到某个类的程序集信息
            Console.WriteLine(type.Assembly);
            Console.WriteLine("****************************************************");
            //获取类中的所有公共成员的类型信息
            Type t = typeof(Test);
            MemberInfo[] infos = t.GetMembers();
            for (int i = 0; i < infos.Length; i++) { Console.WriteLine(infos[i]); }
            Console.WriteLine("****************************************************");
            

            //获取类的公共构造函数并调用
            //1.获取所有构造函数信息
            ConstructorInfo[] ctors = t.GetConstructors();
            for (int i = 0; i < ctors.Length; i++) { Console.WriteLine(ctors[i]); }
            Console.WriteLine("****************************************************");
            //2.获取其中一个构造函数并执行
            /*
             构造函数的获取需要传入一个Type数组,用于存储该构造函数的参数类型
             构造函数的执行,需要传入一个object数组,用于按顺序传入参数
             */
            //获取无参构造
            ConstructorInfo info = t.GetConstructor(new Type[0]);
            //执行无参构造(对于无参构造函数的Invoke时直接传null)
            Test obj = info.Invoke(null) as Test;
            Console.WriteLine(obj.j);
            //获取有参构造
            ConstructorInfo info2 = t.GetConstructor (new Type[] { typeof(int)});
            obj = info2.Invoke(new object[] { 2 })as Test;
            Console.WriteLine(obj.str);

            ConstructorInfo info3 = t.GetConstructor(new Type[] {typeof(int),typeof(string)});
            obj = info3.Invoke(new object[] { 4,"yyyy"}) as Test;
            Console.WriteLine(obj.str);


            //获取类的公共成员变量
            //1.得到所有成员变量的信息
            Console.WriteLine("****************************************************");
            FieldInfo[] fieldInfos = t.GetFields();
            for (int i = 0; i < fieldInfos.Length; i++) { Console.WriteLine(fieldInfos[i]); }
            Console.WriteLine("****************************************************");
            //2.得到指定名称的公共变量的信息
            FieldInfo infoJ = t.GetField("j");
            Console.WriteLine(infoJ);
            //3.利用反射获取和设置对象的值
            Test test = new Test();
            test.j = 99;
            test.str = "2222";
            //通过反射获取对应变量的值
            Console.WriteLine(infoJ.GetValue(test));
            //通过反射设定对应变量的值
            infoJ.SetValue(test, 100);
            Console.WriteLine(infoJ.GetValue(test));

            //获取类的公共成员变量方法
            Console.WriteLine("****************************************************");
            Type strType = typeof(string);
            //1.获取所有公共成员方法
            MethodInfo[] methods = strType.GetMethods();
            for (int i = 0; i < methods.Length; i++) 
            {
                Console.WriteLine(methods[i]);
            }
            //2.获取某个公共成员方法
            //若存在成员方法的有参重载,利用Type数组表示参数类型
            MethodInfo subStr = strType.GetMethod("Substring",
                new Type[] { typeof(int),typeof(int) });
            //3.调用某个成员方法
            string str = "Hello,World!";
            Console.WriteLine("****************************************************");
            //第一个参数传入要调用该方法的对象,然后传入object数组来顺序传入参数
            //对于静态成员方法,第一个参数直接传入null
            object result =  subStr.Invoke(str, new object[] { 7, 5 });
            Console.WriteLine(result);
            #endregion
        }
    }
}
相关推荐
AI情绪识别开源1 小时前
检信 ALLEMOTION OS 加密打包可执行程序 — 全面测试报告版本: v1.3功能测试 / 性能测试 /
开发语言·数据结构·人工智能·功能测试
「QT(C++)开发工程师」2 小时前
C++ auto 用法详解
开发语言·c++
OPEN-F2 小时前
C++STL教程:容器适配器与实用工具
开发语言·c++
yaoxin5211232 小时前
507. Java 反射 - 在 BeanFactory 中实现依赖注入
java·开发语言
OPEN-F2 小时前
C++模板教程:变参模板、折叠表达式与SFINAE
java·开发语言·c++
有点。2 小时前
C++二叉搜索树进阶
开发语言·c++
HugoStudio_SWAN3 小时前
【擦除重绘】C++ 控制台动画:弹跳 Logo DVD 屏保效果
开发语言·c++·学习·程序人生
kyle~4 小时前
C++_STL---迭代器失效
开发语言·c++
Brilliantwxx5 小时前
【C语言】 初入嵌入式C语言复习(基础+进阶面试题)
c语言·开发语言