zoukankan      html  css  js  c++  java
  • vs2010新特性(下)

    1)    dynamic

    C#3.0中有一个动态类型,var,它可以定义不同的类型,系统在第一次编译时会根据上下文来判断这个变量的准确类型。

    下面看个例子:

    C#代码:

    static void Main(string[] args)

            {

                var i = 10;

                var d = 1.2;

                var f = 1.1f;

                var str = new string[] { "a","b"};

            }

    IL代码:

    .method private hidebysig static void Main(string[] args) cil managed

    {

     .entrypoint

     // 代码大小       50 (0x32)

     .maxstack 3

     .locals init ([0] int32 i,

               [1] float64 d,

               [2] float32 f,

               [3] string[] str,

               [4] 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: 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是个引用类型,是真的吗?

    现在我们从装折箱角度来看一下这dynamicobject的区别。

         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 iobject oboxobject oint iunbox,但dynamic d = i; int k = (int)d;前一行代码是box,但后一行就不是简单的unbox,看来objectdynamic则是不同的,是一个全新的类型,当然低层做了很多工作。

    vardynamic还一个区别是应用范围,var只能在类成员内部去应用,也就是来充当类成员的局部变量,但dynamic的应用范围就大了,他和一个基本的类型是一样的,可以在有其他类型的任何地方应用。也就是我们的变量动态到任何地方了,不像var只是在一定范围内。

    dynamic虽然简化了我们的定义,但这是以牺牲系统性能为代价的。所以大家最好能有准确的数据类型。
    ****欢迎关注我的asp.net core系统课程****
    《asp.net core精要讲解》 https://ke.qq.com/course/265696
    《asp.net core 3.0》 https://ke.qq.com/course/437517
    《asp.net core项目实战》 https://ke.qq.com/course/291868
    《基于.net core微服务》 https://ke.qq.com/course/299524
  • 相关阅读:
    免费的编程中文书籍索引【转】
    Linux字符集的查看及修改【转】
    expect学习笔记及实例详解【转】
    mycat学习笔记
    Vue-loader 开启压缩后的一些坑
    使用webpack搭建vue开发环境
    基于webpack和vue.js搭建开发环境
    Sublime Text 3 常用插件以及安装方法(vue 插件)
    NodeJS、NPM安装配置步骤(windows版本)
    Https方式使用Git@OSC设置密码的方式
  • 原文地址:https://www.cnblogs.com/axzxs2001/p/1341368.html
Copyright © 2011-2022 走看看