用 Reflector 发现这个类 (System.Internal) 发现里面有这么三个静态方法:
CommonlyUsedGenericInstantiations_HACK
NullableHelper_HACK<T>
SZArrayHelper_HACK<T>

它们的名字很奇怪, 方法里的内容更奇怪, 比如 CommonlyUsedGenericInstantiations_HACK 里的代码是:
private static void CommonlyUsedGenericInstantiations_HACK()
{
    
new ArraySegment<byte>(new byte[1], 00);
    
new Dictionary<charobject>();
    
new Dictionary<short, IntPtr>();
    
new Dictionary<intbyte>();
    
new Dictionary<intint>();
    
new Dictionary<intobject>();
    
new Dictionary<IntPtr, short>();
    
new Dictionary<objectchar>();
    
new Dictionary<object, Guid>();
    
new Dictionary<objectint>();
    NullableHelper_HACK
<bool>();
    NullableHelper_HACK
<byte>();
    NullableHelper_HACK
<char>();
    NullableHelper_HACK
<DateTime>();
    NullableHelper_HACK
<decimal>();
    NullableHelper_HACK
<double>();
    NullableHelper_HACK
<Guid>();
    NullableHelper_HACK
<short>();
    NullableHelper_HACK
<int>();
    NullableHelper_HACK
<long>();
    NullableHelper_HACK
<float>();
    NullableHelper_HACK
<TimeSpan>();
    
new List<bool>();
    
new List<byte>();
    
new List<DateTime>();
    
new List<decimal>();
    
new List<double>();
    
new List<Guid>();
    
new List<short>();
    
new List<int>();
    
new List<long>();
    
new List<TimeSpan>();
    
new List<sbyte>();
    
new List<float>();
    
new List<ushort>();
    
new List<uint>();
    
new List<ulong>();
    
new List<KeyValuePair<objectobject>>();
    RuntimeType.RuntimeTypeCache.Prejitinit_HACK();
    
new CerArrayList<RuntimeMethodInfo>(0);
    
new CerArrayList<RuntimeConstructorInfo>(0);
    
new CerArrayList<RuntimePropertyInfo>(0);
    
new CerArrayList<RuntimeEventInfo>(0);
    
new CerArrayList<RuntimeFieldInfo>(0);
    
new CerArrayList<RuntimeType>(0);
    
new KeyValuePair<charushort>('\0'0);
    
new KeyValuePair<ushortdouble>(0double.MinValue);
    SZArrayHelper_HACK
<bool>(null);
    SZArrayHelper_HACK
<byte>(null);
    SZArrayHelper_HACK
<DateTime>(null);
    SZArrayHelper_HACK
<decimal>(null);
    SZArrayHelper_HACK
<double>(null);
    SZArrayHelper_HACK
<Guid>(null);
    SZArrayHelper_HACK
<short>(null);
    SZArrayHelper_HACK
<int>(null);
    SZArrayHelper_HACK
<long>(null);
    SZArrayHelper_HACK
<TimeSpan>(null);
    SZArrayHelper_HACK
<sbyte>(null);
    SZArrayHelper_HACK
<float>(null);
    SZArrayHelper_HACK
<ushort>(null);
    SZArrayHelper_HACK
<uint>(null);
    SZArrayHelper_HACK
<ulong>(null);
    SZArrayHelper_HACK
<CustomAttributeTypedArgument>(null);
    SZArrayHelper_HACK
<CustomAttributeNamedArgument>(null);
}

这是看上去完全没有意义的代码啊... 而且其中调用 SZArrayHelper_HACK<T> 的地方传进去的参数是 null, 必然会抛出异常的:
private static void SZArrayHelper_HACK<T>(SZArrayHelper oSZArrayHelper)
{
    oSZArrayHelper.get_Count
<T>();
    oSZArrayHelper.get_Item
<T>(0);
    oSZArrayHelper.GetEnumerator
<T>();
}
();
}


不解的我Google之, 只搜到一篇相关的文章, 作者觉得这和JIT的编译效率有关, 和我的猜想也差不多, 但是没有任何地方调用它的方法啊.. 何况调用它还有抛出异常..
该不会是VM调用了它?
于是我想到了传说中的 SSCLI(Shared Source CLI, 就是共享源代码的CLI实现, 涵盖了.Net Framework (CLR, BCL, Compiler 的核心源代码)) ...
找到 System.Internal 类的源文件, 里面赫然写道:
// ==++==
// 
//   
//    Copyright (c) 2006 Microsoft Corporation.  All rights reserved.
//   
//    The use and distribution terms for this software are contained in the file
//    named license.txt, which can be found in the root of this distribution.
//    By using this software in any fashion, you are agreeing to be bound by the
//    terms of this license.
//   
//    You must not remove this notice, or any other, from this software.
//   
// 
// ==--==
/*
============================================================
**
** This file exists to contain miscellaneous module-level attributes
** and other miscellaneous stuff.
**
**
** 
===========================================================
*/
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Reflection;


[assembly:DefaultDependencyAttribute(LoadHint.Always)]
// mscorlib would like to have its literal strings frozen if possible
[assembly: System.Runtime.CompilerServices.StringFreezingAttribute()]

namespace System
{
    
static class Internal
    {
        
// This method is purely an aid for NGen to statically deduce which
        
// instantiations to save in the ngen image.
        
// Otherwise, the JIT-compiler gets used, which is bad for working-set.
        
// Note that IBC can provide this information too.
        
// However, this helps in keeping the JIT-compiler out even for
        
// test scenarios which do not use IBC.
        
// This can be removed after V2, when we implement other schemes
        
// of keeping the JIT-compiler out for generic instantiations.

        
static void CommonlyUsedGenericInstantiations_HACK()
        {
            
// Make absolutely sure we include some of the most common 
            
// instantiations here in mscorlib's ngen image.
            
// Note that reference type instantiations are already included
            
// automatically for us.

            
new ArraySegment<byte>(new byte[1], 00);

            
new Dictionary<Char, Object>();

             ................

            SZArrayHelper_HACK<UInt64>(null);

            SZArrayHelper_HACK
<CustomAttributeTypedArgument>(null);
            SZArrayHelper_HACK
<CustomAttributeNamedArgument>(null);
        }

        
static T NullableHelper_HACK<T>() where T : struct
        {
            Nullable.Compare
<T>(nullnull);    
            Nullable.Equals
<T>(nullnull); 
            Nullable
<T> nullable = new Nullable<T>();
            
return nullable.GetValueOrDefault();
        }       

        
static void SZArrayHelper_HACK<T>(SZArrayHelper oSZArrayHelper)
        {
            
// Instantiate common methods for IList implementation on Array
            oSZArrayHelper.get_Count<T>();
            oSZArrayHelper.get_Item
<T>(0);
            oSZArrayHelper.GetEnumerator
<T>();
        }
    }
}

看完它的注释, 虽然不是太懂 (IBC是什么?), 但也大概有个答案了:
这个类存在的意义是为了让这些一般的泛型类型的 Native Code 能在 Native Image 中存在 (我们都知道安装.Net Framework的时候, 像 Mscorlib.dll 这样的程序集已经安装到了 GAC 中了), 避免了 JIT 在运行时进行编译 (生成泛型类型的 Native Code)而造成的效率损失.
注释中还提到, 下一个版本的 .Net CLR(4.0? 3.0? 谁知道呢..) 将不会有这个 Trick.. 开发人员将会使用另外一种泛型的实现方案.

关于 .Net 2.0 中的泛型在运行时是如何编译的, 可以参考 Introducing Generics in the CLR

相关文章:

  • 2022-12-23
  • 2021-11-09
  • 2021-06-22
  • 2021-07-09
  • 2021-12-22
  • 2021-05-30
猜你喜欢
  • 2022-12-23
  • 2021-07-04
  • 2022-12-23
  • 2021-11-27
  • 2021-12-14
  • 2021-10-22
  • 2022-12-23
相关资源
相似解决方案