c# - 奇怪的通用行为

标签 c# .net generics

在以下代码中,装箱发生(在 Generic.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);
        }
    }
}

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

它是装箱并调用 Console.WriteLine(object)。我假设它只会调用 Console.WriteLine(string)。这是怎么回事?

最佳答案

不,它实际上不会装箱。来自 box 指令的 ECMA-335 描述:

If typeTok is a reference type, the box instruction does returns val unchanged as obj.

换句话说,如果您在引用类型上调用 box 是无害的。

(JIT 无论如何都会为引用类型和值类型生成单独的 native 代码,所以我怀疑这最终会在引用类型版本中被完全删除。)

关于c# - 奇怪的通用行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6678944/

相关文章:

c# - 在 ServiceStack 4 和 MySQL 中使用 Guid ID

.net - ASP.NET:为什么登录引用不包括端口

swift - 将 Collection 的子序列转换为 String

c# - 检查表是否为空后插入数据

java - 如何在代码中查找语义格式错误的参数化类型的位置。 JBoss Weld 抛出 java.lang.reflect.MalformedParameterizedTypeException

java - 泛型类型声明导致错误

c# - 新手继承问题

c# - 如何访问 InnerException 的 InnerExceptions 属性?

c# - 什么是NullReferenceException,如何解决?

c# - 如何在发布版本中删除对 log4net 的依赖?