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虽然简化了我们的定义,但这是以牺牲系统性能为代价的。所以大家最好能有准确的数据类型。















本文转自桂素伟51CTO博客,原文链接:http://blog.51cto.com/axzxs/149950 ,如需转载请自行联系原作者



相关文章
|
6月前
|
Java 编译器 API
1.8的新特性(二)
有1.8的新特性了解过吗? (注意了解其他版本新特征) +JDK更新认识
17 0
|
8月前
|
安全 编译器 C++
2022-9-20-C++11新特性(二)
2022-9-20-C++11新特性
38 0
|
4月前
|
存储 安全 编译器
C++ 11新特性详解2
C++ 11新特性详解
49 0
|
5月前
|
编译器 C++ 容器
c++11新特性
c++11新特性
|
6月前
|
Java 编译器 API
1.8的新特性
有1.8的新特性了解过吗? (注意了解其他版本新特征) +JDK更新认识 · Lambda表达式 · 函数式接口 函数式编程 · 方法引用和构造器调用
17 0
|
10月前
|
算法 安全 编译器
【C++】C++11常用新特性
C++11增加的语法特性非常篇幅非常多,我们这里没办法一 一讲解,所以本节主要讲解实际中比较实用的语法。
51 2
|
存储 C++ 容器
C++11新特性总结(1)
C++11新特性总结(1)
C++11新特性总结(1)
|
安全 C++
C++11新特性总结(2)
C++11新特性总结(2)
C++11新特性总结(2)
|
开发框架 .NET 编译器
C# 10的新特性
C# 10的新特性
167 0
|
Java C#
说说 C# 8 using 新特性
说说 C# 8 using 新特性
139 0