可以检查核心C#功能的内部

Nic*_*ock 2 c# implementation il mscorlib

今天我很震惊,有比较内心的倾向Buffer.BlockCopy,Array.CopyTo. 我很好奇,看看是否在幕后Array.CopyTo被召唤Buffer.BlockCopy.这背后没有实际用途,我只想进一步了解C#语言及其实现方式.不要跳枪并指责我微观优化,但你可以指责我好奇!

当我在mscorlib.dll上运行ILdasm时,我收到了这个 Array.CopyTo

.method public hidebysig newslot virtual final 
    instance void  CopyTo(class System.Array 'array',
                          int32 index) cil managed
{
  // Code size       0 (0x0)
} // end of method Array::CopyTo
Run Code Online (Sandbox Code Playgroud)

这个 Buffer.BlockCopy

.method public hidebysig static void  BlockCopy(class System.Array src,
                                            int32 srcOffset,
                                            class System.Array dst,
                                            int32 dstOffset,
                                            int32 count) cil managed internalcall
{
  .custom instance void System.Security.SecuritySafeCriticalAttribute::.ctor() = ( 01 00 00 00 ) 
} // end of method Buffer::BlockCopy
Run Code Online (Sandbox Code Playgroud)

坦率地说,这令我感到困惑.我从未在我没有创建的dll/exe上运行ILdasm.这是否意味着我将无法看到这些功能是如何实现的?搜索周围只显示了一个stackoverflow问题,Marc Gravell说

[ Buffer.BlockCopy]基本上是原始内存副本的包装器

虽然很有见地,但如果Array.CopyTo打电话,它不会回答我的问题Buffer.BlockCopy.我特别感兴趣的是,如果我能够看到这两个函数是如何实现的,如果我将来有关于C#内部的问题,我是否有可能对其进行调查.还是我运气不好?

Han*_*ant 9

这里最大的问题是你正在查看参考程序集,特别是对于那些.NET 4,从你发布的内容来看.哪些是特殊程序集,它们的所有IL都被剥离出来并且只包含元数据.这是.NET 4中的新功能,它解决了早期版本.NET中的一个老问题.参考组件只是GAC中安装的实际组件的副本.

这导致了麻烦,在以后的版本和破坏程序的服务包中进行了更改.特别是WaitHandle.WaitOne(int)重载是臭名昭着的,它是在.NET 3.0(又名.NET 2.0 SP1)中添加的.并且不知不觉地被程序员使用,发现重载更容易使用heckofalot然后神秘的WaitOne(int,bool)重载.但是问题是他们的程序将不再在原始的.NET 2.0发行版上运行,从而产生MissingMethodException.

添加此超载是普遍相当顽皮的事情,他们修改mscorlib.dll中却丝毫没有改变它的[的AssemblyVersion.通过在.NET 4中提供单独的引用程序集,不再出现此问题.Microsoft现在可以在不破坏任何内容的情况下修改.NET类型的公共接口.并且已经热情地完成了这项工作,一些.NET 4中间版本已经流畅播放,没有任何人注意到.

因此,请务必反汇编mscorlib.dll 的实际版本,即GAC中的版本.其中.NET 4存储在不同的目录中,c:\ windows\microsoft.net\assembly,而不是c:\ windows\assembly.它不再受explorer shell命名空间扩展的保护,您只需使用File + Open浏览GAC目录即可.您将在C:\ Windows\Microsoft.NET\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089目录中找到32位版本.

这不是故事的结束,当你向下钻取时,你会发现Array.CopyTo()调用一个名为Array.Copy()的内部辅助方法,该方法具有[MethodImpl(MethodImplOptions.InternalCall)]属性.再一次,没有方法体.该属性告诉即时编译器该方法实际上是在CLR内部的C++中实现的.请参阅此答案以了解如何查看此类方法的源代码.