vs2010新特性(下)

 IL_0001: ldc.i4.s   10
 IL_0003: stloc.0
 IL_0004: ldc.r8     1.2
 IL_000d: stloc.1
 IL_000e: ldc.r4     1.1
  IL_0013: stloc.2
 IL_0014: ldc.i4.2
 IL_0015: newarr     [mscorlib]System.String
 IL_001a: stloc.s    CS$0$0000
 IL_001c: ldloc.s    CS$0$0000
 IL_001e: ldc.i4.0
 IL_001f: ldstr      "a"
 IL_0024: stelem.ref
 IL_0025: ldloc.s    CS$0$0000
 IL_0027: ldc.i4.1
 IL_0028: ldstr      "b"
 IL_002d: stelem.ref
 IL_002e: ldloc.s    CS$0$0000
 IL_0030: stloc.3
 IL_0031: ret
} // end of method Program::Main
我们可以看到,在C# 中定义了几种类型,都是以var 定义的,并且都是方法内部的局部变量。但在IL 中我们会看到(红色代码)定义的局部变量会有准确的类型。
下面我们来看一下在vs2010 中,C#4.0 中的一个新的类型dynamic ,我们同样来定义一个方法:
static void Main()
        {
            var i = 10;
            var d = 1.2;
            var f = 1.1f;
            var str = new string[] { "a", "b" }; 
     
            dynamic i1 = 10;
            dynamic d1 = 1.2;
            dynamic f1 = 1.1f;
            dynamic str1 = new string[] { "a", "b" }; 
        }
再来看看他的IL
.method private hidebysig static void Main() cil managed
{
 .entrypoint
 // Code size       117 (0x75)
 .maxstack 3
 .locals init ([0] int32 i,
           [1] float64 d,
           [2] float32 f,
           [3] string[] str,
           [4] object i1,
           [5] object d1,
           [6] object f1,
           [7] object str1,
           [8] string[] CS$0$0000)
 IL_0000: nop
 IL_0001: ldc.i4.s   10
 IL_0003: stloc.0
 IL_0004: ldc.r8     1.2
 IL_000d: stloc.1
 IL_000e: ldc.r4     1.1
 IL_0013: stloc.2
 IL_0014: ldc.i4.2
 IL_0015: newarr     [mscorlib]System.String
 IL_001a: stloc.s    CS$0$0000
 IL_001c: ldloc.s    CS$0$0000
 IL_001e: ldc.i4.0
 IL_001f: ldstr      "a"
 IL_0024: stelem.ref
 IL_0025: ldloc.s    CS$0$0000
 IL_0027: ldc.i4.1
 IL_0028: ldstr      "b"
 IL_002d: stelem.ref
 IL_002e: ldloc.s    CS$0$0000
 IL_0030: stloc.3
 IL_0031: ldc.i4.s   10
 IL_0033: box        [mscorlib]System.Int32
 IL_0038: stloc.s    i1
 IL_003a: ldc.r8     1.2
 IL_0043: box        [mscorlib]System.Double
 IL_0048: stloc.s    d1
 IL_004a: ldc.r4     1.1
 IL_004f: box        [mscorlib]System.Single
 IL_0054: stloc.s    f1
 IL_0056: ldc.i4.2
 IL_0057: newarr     [mscorlib]System.String
 IL_005c: stloc.s    CS$0$0000
 IL_005e: ldloc.s    CS$0$0000
 IL_0060: ldc.i4.0
 IL_0061: ldstr      "a"
  IL_0066: stelem.ref
 IL_0067: ldloc.s    CS$0$0000
 IL_0069: ldc.i4.1
 IL_006a: ldstr      "b"
 IL_006f: stelem.ref
 IL_0070: ldloc.s    CS$0$0000
 IL_0072: stloc.s    str1
 IL_0074: ret
} // end of method File::Main
我们看到C# 中的代码基本没变,就是把var 换成dynamic ,在IL 中,var 的没有变化,但用dynamic 定义的类型(红 色代码部分) ,除了string[] 外都是object 类型,如果这样看来,dynamic 其不是就是object 吗?不是的,往下看,会发现每个类型在初始化时就个box ,就是装箱,装到dynamic 这种类型中了,看来dynamic 是个引用类型,是真的吗?
 
现在我们从装折箱角度来看一下这dynamic object 的区别。
     static void Method()
        {         
            int i = 10;
            object o = i;
            int j = (int)o;
         
            dynamic d = i;
            int k = (int)d;
        }
来看一下IL
.method private hidebysig static void Method() cil managed
{
 // Code size       89 (0x59)
  .maxstack 4
 .locals init ([0] int32 i,
           [1] object o,
           [2] int32 j,
           [3] object d,
           [4] int32 k)
 IL_0000: nop
 IL_0001: ldc.i4.s   10
 IL_0003: stloc.0
 IL_0004: ldloc.0
 IL_0005: box        [mscorlib]System.Int32
 IL_000a: stloc.1
 IL_000b: ldloc.1
 IL_000c: unbox.any [mscorlib]System.Int32
 IL_0011: stloc.2
 IL_0012: ldloc.0
 IL_0013: box        [mscorlib]System.Int32
 IL_0018: stloc.3
 IL_0019: ldsfld     class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Func`3<class [System.Core]System.Scripting.Actions.CallSite,object,int32>> ConsoleApplication2.File/'<Method>o__SiteContainer0'::'<>p__Site1'
 IL_001e: brtrue.s   IL_0041
 IL_0020: call       class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
 IL_0025: ldtoken    [mscorlib]System.Int32
 IL_002a: call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
 IL_002f: ldc.i4.1
 IL_0030: newobj     instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpConversionPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
                                                                                                                class [mscorlib]System.Type,
                                                                                                                valuetype [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpConversionPayload/ConversionKindEnum)
 IL_0035: call       class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Func`3<class [System.Core]System.Scripting.Actions.CallSite,object,int32>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
 IL_003a: stsfld     class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Func`3<class [System.Core]System.Scripting.Actions.CallSite,object,int32>> ConsoleApplication2.File/'<Method>o__SiteContainer0'::'<>p__Site1'
 IL_003f: br.s       IL_0041
 IL_0041: ldsfld     class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Func`3<class [System.Core]System.Scripting.Actions.CallSite,object,int32>> ConsoleApplication2.File/'<Method>o__SiteContainer0'::'<>p__Site1'
 IL_0046: ldfld      !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Func`3<class [System.Core]System.Scripting.Actions.CallSite,object,int32>>::Target
 IL_004b: ldsfld     class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Func`3<class [System.Core]System.Scripting.Actions.CallSite,object,int32>> ConsoleApplication2.File/'<Method>o__SiteContainer0'::'<>p__Site1'
 IL_0050: ldloc.3
 IL_0051: callvirt   instance !2 class [System.Core]System.Func`3<class [System.Core]System.Scripting.Actions.CallSite,object,int32>::Invoke(!0,
                                                                                                                                               !1)
 IL_0056: stloc.s    k
 IL_0058: ret
} // end of method File::Method
我们会发现int i object o box object o int i unbox ,但dynamic d = i; int k = (int)d; 前一行代码是box ,但后一行就不是简单的unbox ,看来object dynamic 则是不同的,是一个全新的类型,当然低层做了很多工作。
var dynamic 还一个区别是应用范围,var 只能在类成员内部去应用,也就是来充当类成员的局部变量,但dynamic 的应用范围就大了,他和一个基本的类型是一样的,可以在有其他类型的任何地方应用。也就是我们的变量动态到任何地方了,不像var 只是在一定范围内。
 
dynamic 虽然简化了我们的定义,但这是以牺牲系统性能为代价的。所以大家最好能有准确的数据类型。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值