C#探索之路(1):反射和特性(一)

C#探索之路(1):反射和特性(一)

前言:

前段时间将Unity3d中UGUI组件精简复盘落下了帷幕,后期博主可能会从设计模式,部分的算法,以及从UGUI实际操作上、或者从Unity3D部分的一些小游戏Demo上去做文章。但是在此之前,还是多多了解和使用使用C#吧,这就是我之前提到了框架,lua的框架在便捷的同时,也会增加一个人的编程语言的惰性,虽然不是不懂,但是久而久之,使用少了,也就没有那么熟练了。所以近期可能会更多的从C#或者Unity的相关小型Demo的讲解入手去练习与讲解。

话不多说,我们直接进入正题~ 今天我们讲的就是C#中的反射和特性(一)啦~

1.什么是元数据,什么是反射

程序是用来处理数据的,文本和特性都是数据,而我们程序本身(类的定义和BLC中的类)这些也是数据。
有关程序及其类型的数据被称为元数据(metadata),它们保存在程序的程序集中。
程序在运行时,可以查看其它程序集或其本身的元数据。一个运行的程序查看本身的元数据或者其他程序集的元数据的行为叫做反射。

2.Type类

预定义类型(int long 和string等),BCL中的类型(Console,IEnumerable等)和程序员自定义类型(MyClass,MyDel等)。 每种类型都有自己的成员和特性。
BCL声明了一个叫做Type的抽象类,它被设计用来包含类型的特性。使用这个类的对象能让我们获取程序使用的类型的信息。
由于 Type是抽象类,因此不能利用它去实例化对象。关于Type的重要事项如下:
对于程序中用到的每一个类型,CLR都会创建一个包含这个类型信息的Type类型的对象。
程序中用到的每一个类型都会关联到独立的Type类的对象。
不管创建的类型有多少个示例,只有一个Type对象会关联到所有这些实例

3.System.Type类部分成员

成员 成员类型 描述
Name 属性 返回类型的名字
Namespace 属性 返回包含类型声明的命名空间
Assembly 属性 返回声明类型的程序集。
GetFields 方法 返回类型的字段列表
GetProperties 方法 返回类型的属性列表
GetMethods 方法 返回类型的方法列表

那就举个例子吧:

我们定义一个Myclass类,并且定义好相关的字段,属性以及方法,我们就通过反射的原理来了解他们实际上代表的意义吧

Myclass.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test_Reflection_and_characteristic
{
    public class Myclass
    {
        private int id;
        private int age;
        public int height;
        public int weight;
        private string Sex { get; set; }
        public string Name { get; set; }

        public void Test()
        {

        }

        public void Test2()
        {

        }

        private void Test3()
        {

        }

    }
}

在主程序中我们通过反射的关系去拿到这个Myclass类的相关信息

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

namespace Test_Reflection_and_characteristic
{
    class Program
    {
        static void Main(string[] args)
        {
            Myclass my = new Myclass();//每一个类对应一个type对象,这个type对象存储了这个类,有哪些方法跟哪些方法以及哪些成员
            Type testType = my.GetType();//一个类中的数据是存储在对象中的,但是type对象只存储类的成员
            Console.WriteLine("输出 testType所引用的命名空间:{0}", testType);
            Console.WriteLine("获取当前testType所引用的类名:{0}", testType.Name);
            Console.WriteLine("输出当前tesType中的程序集:{0}", testType.Assembly);
            Console.WriteLine("输出与当前testType相关联的属性:{0}", testType.Attributes);
        }
    }
}

输出结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nsbsQdBW-1631380047788)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210912001209264.png)]

我想通过这种方式输出表达出来已经足够明确了吧

同时当我们想要通过反射去访问到类里面的类的字段、属性与方法也是可以的

在主程序中补充代码如下:

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

namespace Test_Reflection_and_characteristic
{
    class Program
    {
        static void Main(string[] args)
        {
            Myclass my = new Myclass();//每一个类对应一个type对象,这个type对象存储了这个类,有哪些方法跟哪些方法以及哪些成员
            Type testType = my.GetType();//一个类中的数据是存储在对象中的,但是type对象只存储类的成员
            Console.WriteLine("输出 testType所引用的命名空间:{0}", testType);
            Console.WriteLine("获取当前testType所引用的类名:{0}", testType.Name);
            Console.WriteLine("输出当前tesType中的程序集:{0}", testType.Assembly);
            Console.WriteLine("输出与当前testType相关联的属性:{0}", testType.Attributes);


            //通过FieldInfo去访问字段
            FieldInfo[] array = testType.GetFields();
            foreach (FieldInfo info in array)
            {
                //注意只有public公有的字段才能访问到,private私有字段是无法访问到的
                Console.WriteLine("输出当前testType中所含有的字段{0}", info.Name);
            }

            PropertyInfo[] array2 = testType.GetProperties();
            foreach (PropertyInfo info in array2)
            {
                //注意只有public公有的属性才能访问到,private私有属性是无法访问到的
                Console.WriteLine("输出当前testType中所含有的属性{0}", info.Name);
            }

            MethodInfo[] array3 = testType.GetMethods();
            foreach (MethodInfo info in array3)
            {
                //注意只有public公有的方法才能访问到,private私有方法是无法访问到的
                Console.WriteLine("输出当前testType中所含有的方法{0}", info.Name);
            }
        }
    }
}

编译结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K3vWB84g-1631380047797)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210912001412768.png)]

注意:无论是类的字段和属性以及方法,都是只能访问到public权限下的成员与数据。后面的Equals方法,GetHashCode以及GetType、Tostring方法是Type类里面自己重写的。想要了解的话,直接找到主程序中的Type,按下F12键就知道啦

如图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VMm4njtY-1631380047803)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210912003544846.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eRsOcT7y-1631380047806)(D:\CSDN博客博文\CSDN表情包\CD136E8F825E7814554E99D9869E27D0.jpg)]
在这里插入图片描述

“哥哥”的快乐你是体会不到的!自己可以慢慢按F12去体会其中的快乐奥,哥哥累了,哥哥要休息一小会儿…。
在这里插入图片描述

如果博客博友对这个章节有更多的内容想要了解的,可以评论哈,等这一个章节结束后,我会根据评论反馈以及自己的能力,将评论中反馈的内容在下一个计划中去制作出对应的内容的哈~在这里插入图片描述
公众号:平平无奇代码猴
也可以搜索:Jackiie_wang 公众号,欢迎大家关注!欢迎催更!留言!

作者:ProMer_Wang

链接:https://blog.csdn.net/qq_43801020/article/details/120245915

本文为ProMer_Wang的原创文章,著作权归作者所有,转载请注明原文出处,欢迎转载!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值