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 ,如需转载请自行联系原作者



相关文章
|
10月前
|
人工智能
逼真到离谱!1000个人类克隆进西部世界,AI相似度85%细节太炸裂
《生成式代理:1000人的模拟》由斯坦福大学等机构完成,利用AI技术成功模拟了1000个真实个体的态度和行为,准确率达85%。研究结合大型语言模型与定性访谈数据,旨在为社会科学研究提供新工具,减少偏见,提升公平性。论文还探讨了隐私和伦理问题,并强调了代理的局限性。
239 13
|
存储 内存技术
逻辑地址和物理地址及逻辑磁盘和物理磁盘
【9月更文挑战第3天】在计算机系统中,逻辑地址与物理地址及逻辑磁盘与物理磁盘是核心概念。逻辑地址由段地址和偏移地址组成,与程序在内存中的实际位置无关;物理地址则是内存中实际的绝对地址,用于直接访问内存数据。物理磁盘指实际存储设备,如硬盘或固态硬盘;逻辑磁盘则是通过分区和格式化创建的存储单元,便于管理和使用。理解这些概念对内存和存储管理至关重要。
886 4
|
XML Java Kotlin
springboot + minio + kkfile实现文件预览
本文介绍了如何在容器中安装和启动kkfileviewer,并通过Spring Boot集成MinIO实现文件上传与预览功能。首先,通过下载kkfileviewer源码并构建Docker镜像来部署文件预览服务。接着,在Spring Boot项目中添加MinIO依赖,配置MinIO客户端,并实现文件上传与获取预览链接的接口。最后,通过测试验证文件上传和预览功能的正确性。
1382 4
springboot + minio + kkfile实现文件预览
|
NoSQL Java Redis
Spring Boot与Redisson的集成
Spring Boot与Redisson的集成
C++ 获取当前程序路径
C++ 获取当前程序路径
|
监控 测试技术
测试思想-流程规范 软件测试缺陷管理流程
测试思想-流程规范 软件测试缺陷管理流程
356 0
|
SQL 分布式计算 Shell
DolphinScheduler教程(01)- 入门(下)
DolphinScheduler教程(01)- 入门(下)
1280 0
|
SQL 安全 Java
logback性能优化详解
logback性能优化详解
1368 0
logback性能优化详解
|
机器学习/深度学习 数据可视化 PyTorch
模型推理加速系列 | 04:BERT加速方案对比 TorchScript vs. ONNX
本文以 BERT-base 的为例,介绍2种常用的推理加速方案:ONNX 和 TorchScript,并实测对比这两种加速方案与原始Pytorch模型格式的inference性能。
|
SQL 分布式计算 Hadoop
编译及使用hive-testbench生成Hive基准测试数据
编译及使用hive-testbench生成Hive基准测试数据
869 0