C#中的反射和特性(一)
前言:
前段时间将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);
}
}
}
输出结果:
我想通过这种方式输出表达出来已经足够明确了吧
同时当我们想要通过反射去访问到类里面的类的字段、属性与方法也是可以的
在主程序中补充代码如下:
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);
}
}
}
}
编译结果:
注意:无论是类的字段和属性以及方法,都是只能访问到public权限下的成员与数据。后面的Equals方法,GetHashCode以及GetType、Tostring方法是Type类里面自己重写的。想要了解的话,直接找到主程序中的Type,按下F12键就知道啦
如图所示:
“哥哥”的快乐你是体会不到的!自己可以慢慢按F12去体会其中的快乐奥,哥哥累了,哥哥要休息一小会儿…。
如果博客博友对这个章节有更多的内容想要了解的,可以评论哈,等这一个章节结束后,我会根据评论反馈以及自己的能力,将评论中反馈的内容在下一个计划中去制作出对应的内容的哈~
作者:ProMer_Wang
链接:https://blog.csdn.net/qq_43801020/article/details/120245915
本文为ProMer_Wang的原创文章,著作权归作者所有,转载请注明原文出处,欢迎转载!