今天我正在浏览.NET Core源代码树,发现在System.Collections.Immutable.ImmutableArray<T>
中有这个模式:
T IList<T>.this[int index]
{
get
{
var self = this;
self.ThrowInvalidOperationIfNotInitialized();
return self[index];
}
set { throw new NotSupportedException(); }
}
这种模式(在本地变量中存储
this
)似乎在该文件中一贯地应用于同一方法中多次引用this
的情况,但当它只被引用一次时则不然。因此我开始思考采用这种方式可能具有的相对优势;在我看来,这种方式的优势很可能与性能相关,因此我进一步探索了这个问题……也许我忽略了其他方面的问题。发出“将
this
存储在本地”模式的CIL似乎看起来像是一个ldarg.0
,然后是ldobj UnderlyingType
,然后是stloc.0
,以便稍后的引用来自于ldloc.0
而不是像使用多个this
那样的裸ldarg.0
。也许
ldarg.0
比ldloc.0
慢得多,但不足以让C#到CIL的转换或JITter寻找优化机会来为我们优化它,因此在结构体实例方法中发出两个ldarg.0
指令时,编写这种看起来奇怪的模式在C#代码中更有意义。更新:或者,您知道,我可以查看该文件顶部的注释,其中explain了正在发生的事情...
struct
,也可能不是线程安全的,因为整个struct
可能会被原地修改。 - xanatos