[C#复习向整合]反射 - Type

一.程序集

程序集是经由编译器编译得到的,供进一步编译执行的那个中间产物.

在windows系统中,它一般表现后缀为 .dll(库文件), 或者是 .exe(可执行文件)的格式

程序集就是我们写的一个代码集合,我们现在写的所有代码,最终都会被编译器翻译为一个程序集供别人使用,比如dll或exe

 运行vs里的代码,会在bin->debug->netcoreapp3.1 生成文件

二.元数据

用来表述数据的数据.

程序中的类,类中的函数,变量等等可以称为程序的元数据

有关程序以及类型的数据被称为元数据,保存在程序集中. 

三.反射

一个运行的程序查看本身或者其他程序的元数据的行为就叫反射

通俗说,程序运行时,通过反射可以得到其他程序集或者自己程序集代码的各种信息,类,函数,变量,对象等等,操作它们.

四.反射作用

反射可以在程序编译后获得信息,所以它提高了程序的拓展性和灵活性

1.程序运行时得到所有元数据,包括元数据的特性

2.程序运行时,实例化对象,操作对象

3.程序运行时创建新的对象,用这些对象执行任务

可以通过反射,在一个程序集里,使用另一个程序集的代码,反射的最大作用.

五.语法相关

1.Type

Type是类的信息类

它是反射功能的基础,是访问元数据的主要方式

使用Type的成员获取有关类型声明的信息,有关类型的成员.

//获取Type
//1.object中的GetType(),参数为对象
int a = 42;
Type _t = a.GetType();
//2.typeof,参数为类型
_t = typeof(int);
//3.通过类名,类名必须包含命名空间
// _t = Type.GetType("Int32");//错误
_t = Type.GetType("System.Int32");
//三种方法指向内存地址是一样的
Console.WriteLine(_t);
Type t = typeof(int);
//得到类的程序集
Console.WriteLine(t.Assembly);

获得类中的所有公共成员

using System;
using System.Reflection;
namespace 反射
{
    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)
        {
            //获取类中的所有公共成员
            //首先得到Type
            Type t = typeof(Test);
            //然后得到所有公共成员
            //需要命名空间 System.Reflection
            MemberInfo[] infos = t.GetMembers();
            for(int i = 0;i<infos.Length;i++)
            {
                //打印所有公共成员
                Console.WriteLine(infos[i]);
            }

            //获取所有构造函数
            ConstructorInfo[] ctors = t.GetConstructors();
            for (int i = 0; i < ctors.Length; i++)
            {
                Console.WriteLine(ctors[i]);
            }
        }
    }
}

获取公共构造函数并调用(续接上一段代码)

//通过反射的方式来实例化对象(调用构造函数)
//1.无参构造
    //先获取无参构造函数
ConstructorInfo info1 = t.GetConstructor(new Type[0]);
    //执行构造函数
Test obj1 = info.Invoke(null) as Test;//无参构造Invoke参数为null即可
//在Test类是同一程序集时,以上内容等价:
//Test obj1 = new Test();
Console.WriteLine(obj1.j);

//2.有参构造
ConstructorInfo info2 = t.GetConstructor(new Type[] { typeof(int) });
Test obj2 = info2.Invoke(new object[] { 2 }) as Test;//参数为2
Console.WriteLine(obj2.j);

ConstructorInfo info3 = t.GetConstructor(new Type[] { typeof(int), typeof(string) });
Test obj3 = info3.Invoke(new object[] { 3, "321" }) as Test;
Console.WriteLine(obj3.j);

获取公共成员变量

//1.获得所有成员变量
FieldInfo[] fieldInfos1 = t.GetFields();
for (int i = 0; i < fieldInfos1.Length; i++)
{
    Console.WriteLine(fieldInfos1[i]);
}

//2.得到指定名称的成员变量
FieldInfo fieldInfos2 = t.GetField("j");//传入变量名
Console.WriteLine(fieldInfos2);

//通过反射来获取和设置对象的值
//拿自身程序集的类为例
Test test = new Test();
test.j = 99;
test.str = "23333";
Console.WriteLine(fieldInfos2.GetValue(test));
fieldInfos2.SetValue(test, 20);//设置值

获得公共成员方法

//获得类的公共成员方法
Type strType = typeof(string);
MethodInfo[] methods = strType.GetMethods();
for (int i = 0; i < methods.Length; i++)
{
    Console.WriteLine(methods[i]);
}
//如果某方法有重载,用Type数组表示参数类型
MethodInfo subStr = 
    strType.GetMethod("Substring", new Type[] { typeof(int), typeof(int) });
//调用
string _str = "Hello World";
//用一个string来保存函数返回的substring
//函数第一个参数为调用方法的对象,等价于_str.Substring(3,5);
//若方法为静态方法,则没有调用对象,不需要第一个参数了
string sub_str = subStr.Invoke(_str, new object[] { 3, 5 }) as string;

资料来源<唐老狮C#教程>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值