vs2010新特性(下)
原创
©著作权归作者所有:来自51CTO博客作者桂素伟的原创作品,请联系作者获取转载授权,否则将追究法律责任
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只是在一定范围内。
下一篇:VS2010中的新特点(上)
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
VS2010 下 使用 Python
Visual Studio 2010的Python支持工具
python hive .net -
vs2010
默认情况下是不显示代码的行号的,但是在编译出错时,可点击下面输出窗口中的错误提示进行定位。但是这样操作起来你有没有感觉到不方便呢。 不显示行号时,代码窗口显示如图:
显示行号 文本编辑器 菜单栏 错误提示 .net -
vs2010下libevent的使用
下载最新的libevent,目前是libevent-2.0.21-stable.tar.gz修改“D:\libevent-2.0.21-stable\event_iocp.c”、“D:\libevent-2.0....
#include #endif #ifdef linux 多线程 -
vs2010调用redis vs2010调用dll文件
VS2010 加载Dll文件
vs2010调用redis 加载 库文件 文件拷贝