C# 反射与Type

在这里插入图片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace reflection
{
    #region 知识点回顾
    // 源语言程序: 某种程序设计语言写成的,比如C、C++、Java等语言写的程序
    // 目标语言程序:二进制数表示的伪机器代码写的程序
    #endregion

    #region 程序集
    // 程序集 就是我们写的一个代码集合
    // 比如一个代码库文件(dll)或者 一个可执行文件(exe)

    #endregion

    #region 元数据
    // 元数据 就是描述数据的数据
    // 程序中的类,类中的函数、变量等等信息就是程序的 元数据
    // 有关程序以及类型的数据被称为 元数据,它们保存在程序集中。
    #endregion

    #region 反射的概念
    // 一个运行的程序查看本身或者其它程序的 元数据的行为 就叫做反射。

    // 在程序运行时,通过反射可以得到其它程序集或者自己程序集代码的各种信息。
    // 类、函数、变量、对象等等,实例化它们、执行它们、操作它们。
    #endregion

    #region 反射的作用
    // 因为反射可以在 程序编译后 获得信息、所以它提高了程序的拓展性和灵活性。
    // 1.程序运行时,得到所有元数据、包括元数据的特性
    // 2.程序运行时,实例化对象、操作对象
    // 3.程序运行时,可以创建新对象,用这些对象执行任务。
    #endregion

    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 Speek()
        {
            System.Console.WriteLine(i.ToString());
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("反射");

            // 相关语法
            #region Type
            // type 类的信息类
            // 是反射功能的基础.
            // 它是访问元数据的主要方式。
            // 使用Type 的成员获取有关类型声明的信息
            // 有关类型的成员 (如构造函数、方法、字段、属性和类的事件)
            #endregion

            #region 获取Type
            // 1.Object中 获取GetType() 可以获取对象的Type
            
            int a = 38;
            Type typeA = a.GetType();
            Console.WriteLine("变量a的类型:" + typeA );

            // 2.通过typeof关键字获取 传入类名
            Type typeB = typeof(int);
           
            Console.WriteLine("typeof 获取类型:" + typeB);

            // 3.通过类的名字 获取Type
            // 注意必须包含命名空间、不然找不到。
            Type typeName = Type.GetType("System.Int32");
            Console.WriteLine("类名 获取类型:" + typeName);

            #endregion

            #region 得到程序集信息
            Console.WriteLine(typeA.Assembly);
            Console.WriteLine(typeB.Assembly);
            Console.WriteLine(typeName.Assembly);

            #endregion

            #region 获取类中的所有公共成员
            // 首先得到Type
            Type tTest = typeof(Test);
            // 得到所有公共成员

            // 需要引用命名空间  using System.Reflection;
            MemberInfo[] infos = tTest.GetMembers();
            foreach (MemberInfo item in infos)
            {
                Console.WriteLine(item);
            }

            #endregion

            #region 获取类中的 公共构造函数并调用
            // 1.获取所有构造函数
            ConstructorInfo[] ctors = tTest.GetConstructors();
            foreach (ConstructorInfo item in ctors)
            {
                Console.WriteLine(item);
            }

            // 2.获取其中一个构造函数 并执行
            // 2-1. 无参构造
            ConstructorInfo ctorInfo = tTest.GetConstructor(new Type[0]); // 传入 Type 数组
            // 执行无参构造
            Test obj =  ctorInfo.Invoke(null) as Test; // 无参构造
            Console.WriteLine(obj.j);
            // 2-2. 得到有参构造
            ConstructorInfo ctorInfo2 = tTest.GetConstructor(new Type[] { typeof(int)}); 
            // 执行无参构造
            Test obj1 = ctorInfo2.Invoke(new object[] { 2 }) as Test; // 无参构造
            obj1.Speek();


            #endregion

            #region 获取类中的 成员变量
            // 1.获取所有成员变量
            FieldInfo[] fieldInfos = tTest.GetFields();
            foreach (FieldInfo item in fieldInfos)
            {
                Console.WriteLine(item);
            }

            // 2.得到指定名称的公共成员变量
            FieldInfo fieldJ = tTest.GetField("j");
            Console.WriteLine(fieldJ);

            // 3.通过 成员变量获取对象的值
            Test test = new Test();
            test.j = 99;
            test.str = "3333";

            // 3-3 通过反射 获取对象的成员变量的值
            Console.WriteLine(fieldJ.GetValue(test));

            // 3-4 通过反射 设置对象的成员变量的值
            fieldJ.SetValue(test, 101);
            Console.WriteLine(fieldJ.GetValue(test));
            #endregion

            #region 获取类中的 方法

            // 1.获取所有方法
            Type strType = typeof(string);
            MethodInfo[] methodInfos = strType.GetMethods();
            foreach (MethodInfo item in methodInfos)
            {
                Console.WriteLine(item);
            }

            // 2.获取其中一个方法 
            MethodInfo strSub = strType.GetMethod("Substring", 
                new Type[] { typeof(int), typeof(int)});

            // 3.使用反射方式 调用方法
            string strHl = "Hello world!";
            // 如果是静态方法  第一个参数 设置为null
            object result = strSub.Invoke(strHl, new object[] { 7, 5 });
            Console.WriteLine(result);
            #endregion

            Console.ReadLine();
        }
    }
}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

廷益--飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值