使用动态关键字构建泛型类型会导致装箱吗?

时间:2016-08-01 16:12:26

标签: c# generics c#-4.0

以下代码是否会导致传递给GenericMethod

的调用中整数的装箱
void GenericMethod<T>(T value)
{
  int test = (dynamic)value;
}

void Main()
{
  GenericMethod(100);
}

3 个答案:

答案 0 :(得分:3)

根据C#规范§4.7动态类型

  

dynamic被视为与object相同,但以下方面除外:

     
      
  • dynamic类型的表达式的操作可以动态绑定(第7.2.2节)。

  •   
  • 如果两者都是候选人,则类型推断(第7.5.2节)会优先dynamic而不是object

  •   

因此,转换为dynamic导致拳击的方式与转换为object相同。

答案 1 :(得分:2)

让我们看看IL代码,看看拳击是否存在:

IL_0000: nop
IL_0001: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite, object, int32>> class Test.Program/'<>o__0`1'<!!T>::'<>p__0'
IL_0006: brfalse.s IL_000a
IL_0008: br.s IL_002e
IL_000a: ldc.i4.0
IL_000b: ldtoken [mscorlib]System.Int32
IL_0010: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0015: ldtoken Test.Program
IL_001a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_001f: call class [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::Convert(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,  class [mscorlib]System.Type,  class [mscorlib]System.Type)
IL_0024: call class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite, object, int32>> class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite, object, int32>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder)
IL_0029: stsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite, object, int32>> class Test.Program/'<>o__0`1'<!!T>::'<>p__0'
IL_002e: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite, object, int32>> class Test.Program/'<>o__0`1'<!!T>::'<>p__0'
IL_0033: ldfld !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite, object, int32>>::Target
IL_0038: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite, object, int32>> class Test.Program/'<>o__0`1'<!!T>::'<>p__0'
IL_003d: ldarg.0
IL_003e: box !!T
IL_0043: callvirt instance int32 class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite, object, int32>::Invoke(!0,  !1)
IL_0048: stloc.0
IL_0049: ret

从这行代码中可以看出:

IL_003e: box !!T

它包装了int

答案 2 :(得分:0)

dynamic类型的变量被编译为object类型的变量,类型dynamic仅在编译时存在,而不是在运行时。

因此,实际上您的示例会将强制类型转换为引用类型的对象。拳击存在于这里