从Unity中的Attribute到AOP(二)
上一篇文章我们初步了解了一下Attributes的含义,并且使用系统自带的Attributes写了点代码。在进一步解剖我们的代码之前,我觉得有个概念可能需要巩固一下:什么是元数据?
我们知道C#代码会被转成MSIL中间语言,而在IL中,程序集的元数据(Metadata)是指以文本的形式保存的该程序集里所有命名空间,类,类中的成员等等。我们可以使用反射的技术把元数据读取出来,还原成IL中代码的树状图。通过反编译,能够基本上还原出代码原来的样子。
如果英文够好的话,可以看看StackOverFlow上的这篇问答。
https://stackoverflow.com/questions/8861065/what-is-metadata-in-net
目前我们已经能够写Attribute,并且使用它来做一些事情。下面我们用MSIL的反编译器看下Attribute的实质是什么。
这个反编译叫ildasm.exe,定位代码到C盘
C:\Program Files (x86)\Microsoft SDKs\Windows\
然后选择版本最高的一个文件夹,定位到
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\文件夹下面。
可以直接双击,也可以右键发送到桌面方便使用。
打开我们上一篇代码的exe文件,可以看到:

MSIL的树形结构非常清晰,从命名空间到类名以及方法的名字,其中.ctor是默认的构造函数。我们并没有在树状结构中发现Attribute的踪迹。随便双击一个加了Attribute的方法,可以得到代码如下:
.method public hidebysig static void LogEngineLow() cil managed
{
.custom instance void [mscorlib]System.Diagnostics.ConditionalAttribute::.ctor(string) = ( 4C 6F ) // ...Low..
.custom instance void [mscorlib]System.Diagnostics.ConditionalAttribute::.ctor(string) = ( 6E 6E ) // ...Engine..
// 代码大小 13 (0xd)
.maxstack
IL_0000: nop
IL_0001: ldstr "LogEngineLow"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret
} // end of method ToolKit::LogEngineLow
在方法中,执行代码之前(IL_0000-IL000c),我们看到了两个构造方法的调用,而这两个构造方法的调用类正是ConditionalAttribute!
再次观察IL代码,可以看到.custom字段,这是专门用来声明自定义的Attributes的。
至此,和我们在第一篇文章中的猜测完全吻合,这是一个类的造型怪异的构造函数。而微软设计这么诡异的语法,我猜测也是为了能够和方法内的代码区分开来,达到低耦合的效果。当代码编译成MSIL的时候,Attributes的构造函数会自动移到目标空间的代码段里,这样看起来就是很正常的代码了。
如果你双击了MSIL中的MANIFEST,就会看到如下的代码:

其实系统自己就调用了很多的Attributes。
我们对IL代码的研究暂时告一段落,下一篇文章将写一个属于自己的Attribute。
从Unity中的Attribute到AOP(二)的更多相关文章
- 从Unity中的Attribute到AOP(七)
本章我们将依然讲解Unity中的Attribute,继续命名空间在UnityEngine里的. PropertyAttribute,这个特性主要来控制变量或者类在Inspector里面的显示方式.和P ...
- 从Unity中的Attribute到AOP(五)
今天主要来讲一下Unity中带Menu的Attribute. 首先是AddComponentMenu.这是UnityEngine命名空间下的一个Attribute. 按照官方文档的说法,会在Compo ...
- 从Unity中的Attribute到AOP(四)
本篇我们将逐一讲解Unity中经常使用的Attribute(Unity对应的文档版本为2018.1b). 首先是Serializable,SerializeField以及NonSerialized,H ...
- 从Unity中的Attribute到AOP(三)
上一篇我们对系统的Attributes进行了MSIL代码的查看,了解到了其本质就是一个类的构造函数.本章我们将编写自己的Attributes. 首先我们定义书的属性代码,如下: [AttributeU ...
- 从Unity中的Attribute到AOP(六)
本文将重点对Unity剩下常用的Attribute进行讲解,其他不常用的Attribute各位可以自行去官方文档查阅. 首先是UnityEngine命名空间下的. ColorUsage,这个主要作用于 ...
- 从Unity中的Attribute到AOP(八)
本文将讲一下在UnityEditor命名空间下的一些特性. CallBackOrder,这个Attribute是所有带callback index的Attribute的基类,由于官方也没有给出详细的说 ...
- 从Unity中的Attribute到AOP(一)
首先来看一下微软官方对Attributes(C#)的定义: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/conce ...
- Unity中使用Attribute
Attribute是c#的语言特性 msdn说明如下: The Attribute class associates predefined system information or user-def ...
- 关于Unity中的transform组件(二)
在Scene视图中的蓝色网格,每一格默认是1米 一.沿着Z轴每秒移动10米 Transform cube_trans; void start(){ this.cube_trans=this.trans ...
随机推荐
- jQuery里使用setinterval
如果第一个参数是一个已写好的函数而不是匿名代码块,一定不要加引号,直接var ** = setinterval{myFunction ,500},只能这样,加括号会直接只调用一次,自然不行,加引号和括 ...
- 从一篇ICLR'2017被拒论文谈起:行走在GAN的Latent Space
同步自我的知乎专栏文章:https://zhuanlan.zhihu.com/p/32135185 从Slerp说起 ICLR'2017的投稿里,有一篇很有意思但被拒掉的投稿<Sampling ...
- 爬取豆瓣电影储存到数据库MONGDB中以及反反爬虫
1.代码如下: doubanmoive.py # -*- coding: utf-8 -*- import scrapy from douban.items import DoubanItem cla ...
- Python的类(class)
python 3.6 官方文档 https://docs.python.org/3.6/index.html python 3.6 的类 https://docs.python.org/3.6/tu ...
- 详解MongoDB管理命令
MongoDB是一个NoSQL数据库系统:一个数据库可以包含多个集合(Collection),每个集合对应于关系数据库中的表:而每个集合中可以存储一组由列标识的记录,列是可以自由定义的,非常灵活,由一 ...
- 《决战大数据:驾驭未来商业的利器》【PDF】下载
内容简介 大数据时代的来临,给当今的商业带来了极大的冲击,多数电商人无不"谈大数据色变",并呈现出一种观望.迷茫.手足无措的状态.车品觉,作为一名经验丰富的电商人,在敬畏大数据的同 ...
- 个人的MySql配置总结
lower_case_table_names参数是用来设置MySQL是否让Schema和数据表大小写敏感,我测试的是在查询界面和MySQL控制台界面无法改变它的值,要在配置文件中改变(先关闭服务),一 ...
- bzoj 4196: [Noi2015]软件包管理器
Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖( ...
- 在海航云中部署 keepalived
**本文属自我学习,不适合转载** 1. 准备工作 1.1 网络方面的准备工作 1.1.1 创建安全组 注意这里要添加 vrrp 协议支持,否则 keepalived 将无法正常工作. 1.1.2 创 ...
- [编织消息框架][JAVA核心技术]动态代理应用7-IRpcSend实现
根据设计生成两个接口,IRpcSend send方法返回数据要求包装成QResult对象 public interface IRpcSend { public <T> QResult< ...