上一篇文章我们初步了解了一下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) = ( 01 00 03 4C 6F 77 00 00 ) // ...Low..
.custom instance void [mscorlib]System.Diagnostics.ConditionalAttribute::.ctor(string) = ( 01 00 06 45 6E 67 69 6E 65 00 00 ) // ...Engine..
// 代码大小 13 (0xd)
.maxstack 8
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。

Unity3D中的Attribute详解(二)的更多相关文章

  1. C#中的Attribute详解(下)

    原文地址:https://blog.csdn.net/xiaouncle/article/details/70229119 C#中的Attribute详解(下) 一.Attribute本质 从上篇里我 ...

  2. Unity3D中的Coroutine详解

    Unity中的coroutine是通过yield expression;来实现的.官方脚本中到处会看到这样的代码. 疑问: yield是什么? Coroutine是什么? unity的coroutin ...

  3. python中常用模块详解二

    log模块的讲解 Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适: logger提供了应用程序可以直接使用的接口API: handler将(logger创建的 ...

  4. 【Unity3D/C#】Unity3D中的Coroutine详解

    Unity中的coroutine是通过yield expression;来实现的.官方脚本中到处会看到这样的代码. 疑问: yield是什么? Coroutine是什么? unity的coroutin ...

  5. js中的attribute详解

    Attribute是属性的意思,文章仅对部分兼容IE和FF的Attribute相关的介绍.attributes:获取一个属性作为对象getAttribute:获取某一个属性的值object.getAt ...

  6. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

  7. 「翻译」Unity中的AssetBundle详解(二)

    为AssetBundles准备资源 使用AssetBundles时,您可以随意将任何Asset分配给所需的任何Bundle.但是,在设置Bundles时,需要考虑一些策略.这些分组策略可以使用到任何你 ...

  8. .Net Attribute详解(一)

    .Net Attribute详解(一) 2013-11-27 08:10 by JustRun, 1427 阅读, 14 评论, 收藏, 编辑 Attribute的直接翻译是属性,这和Property ...

  9. Python中time模块详解

    Python中time模块详解 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. ...

  10. AngularJS select中ngOptions用法详解

    AngularJS select中ngOptions用法详解   一.用法 ngOption针对不同类型的数据源有不同的用法,主要体现在数组和对象上. 数组: label for value in a ...

随机推荐

  1. LayUI 简单的全选和反选小例子

    比较简单实用,直接上代码,主要就是  lay-filter="ischange"   触发事件和  checkbox 的 class="ids" 对上就行: H ...

  2. python笔记:list--pop与remove的区别

    正常情况下: # coding=utf-8 fruit = ['apple', 'pear', 'banana' ] #指定索引删除 fruit.pop(0) #符合元素删除,具体数值 fruit.r ...

  3. Jmeter五、jmeter中的逻辑控制器

    1.simple controller 提供一个块的结构和控制.更方便,更清晰. 嵌套其他的controller 2.loop controller 循环控制器 控制循环次数 可以使用变量 ${__t ...

  4. Navicat Premium 12 安装破解过程 (经过测试)

    @ 目录 下载安装 下载 解压文件目录 安装使用步骤截图 1. 安装navicat120_premium_cs_x64.exe 软件 2. 解压Navicat.Premium 破解补丁.rar 3. ...

  5. 理解 Linux 文件权限

    理解 Linux 文件权限 缺乏安全性的系统不是完整的系统.系统中必须有一套能够保护文件免遭非授权用户浏览或修改的机制.Linux 沿用了 Unix 文件权限的办法,即允许用户和组根据每个文件和目录的 ...

  6. 3vue

    阻止冒泡 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  7. List,Set,Map存取元素各有什么特点 hashMap、hashTable的区别 Arraylist和linkedList的区别

    1.List,Set,Map存取元素各有什么特点? 1.存放 (1)List存放元素是有序,可重复 (2)Set存放元素无序,不可重复 (3)Map元素键值对形式存放,键无序不可重复,值可重复 2.取 ...

  8. algorithm learning for Leetcode (1)

    Leetcode 算法学习(一) 前言:最近学校要求必须学习C++,着重提升技能板块.为了快速升级,我在GitHub上发现了一个开源的学习号召: https://labuladong.github.i ...

  9. L02.从图灵机到通用计算机

    将程序载入到内存(存储器)中,用一个指针指向它, 再载入到cpu(控制器)中进行解释执行   *(取指执行,产生结果) 取指执行 = 控制器从存储器中取出数据后,分析指令,运算器执行逻辑运算. PC= ...

  10. 狂神的学习笔记demo0607

    Ctrl+D 复制此行到下一行 sout   快捷打出System.out.println(); 修饰符 static 静态的 finalf 常量 变量的命名规范 见名知意 类成员变量:首字母小写和驼 ...