简介

C#语言中存在4个未被文档记录(Undocumented)的关键字,在VS、Rider这样的IDE中试图敲出它们时并不会给你任何智能提示,它们分别是:

  1. __makeref
  2. __refvalue
  3. __reftype
  4. __arglist

这4个关键字都涉及对IL代码栈数据的直接操作,并且都与TypedReference有关

TypedReference

那么TypedReference又是什么东西呢?

简而言之,TypedReference就是一个包装了对象指针和对象类型的结构体

__makeref

此关键字用于使用指定对象创建引用此对象的TypedReference

对应的IL代码则是直接使用mkrefany指令创建TypedReference对象

__refvalue

此关键字用于从TypedReference获取对象(类型必须一致或可转换)

对应的IL代码则是直接使用refanyval指令获取对象

因为TypedReference保存的是对象指针,所以可以通过对__refvalue赋值来修改tf所引用变量的值,以实现引用传递的效果

__reftype

此关键字用于从TypedReference中获取对象类型对应的Type

对应的IL代码则是直接使用refanytype指令获取Type对象

结合__makeref,__reftype,__refvalue即可实现无拆装箱开销的通用参数处理

__arglist

此关键字将不定数量的参数打包传递给方法

通过__arglist创建专门用于枚举变长参数列表的ArgIterator,即可对所有参数进行操作

对应的IL代码则是直接通过vararg将参数打包传入方法中

相比使用params关键字传递变长参数,__arglist不对类型有限制,不会产生额外的装箱开销,对应的IL指令也更少

注意事项

不过比较遗憾的是,Unity IL2CPP并不支持以上关键字与TypedReference