奇怪的一般行为

Tom*_*Tom 3 .net c# generics

在以下代码中,发生装箱(在Generic <Type> .Print中):

using System;

namespace Test
{
    static class Program
    {
        static void Main()
        {
            Generic<string> generic = new Generic<string>("test");
            generic.Print();
        }
    }

    class Generic<Type>
    {
        Type value;

        public Generic(Type value)
        {
            this.value = value;
        }

        public void Print()
        {
            Console.WriteLine(value);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ILSpy输出:

.method public hidebysig 
    instance void Print () cil managed 
{
    // Method begins at RVA 0x207d
    // Code size 17 (0x11)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: ldfld !0 class Test.Generic`1<!Type>::'value'
    IL_0006: box !Type
    IL_000b: call void [mscorlib]System.Console::WriteLine(object)
    IL_0010: ret
} // end of method Generic`1::Print
Run Code Online (Sandbox Code Playgroud)

它是拳击并调用Console.WriteLine(对象).我假设它只是调用Console.WriteLine(string).这里发生了什么?

Jon*_*eet 7

不,它实际上不会包装盒子.从ECMA-335说明中的box说明:

如果typeTok是引用类型,则box指令确实将val返回为obj.

换句话说,box如果你在引用类型上调用它,则a 是无害的.

(无论如何,JIT将为引用类型和值类型生成单独的本机代码,因此我怀疑这最终会在引用类型版本中被完全删除.)