装箱拆箱
首先咱们先来看下何为装箱拆箱,这个可以在微软官方文档中Boxing and Unboxing文档中看到答案,咱们就简单的摘要一下相关的描述。
翻译起来会比较抽象,理解起来就是利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的值相互转换,将值类型与引用类型链接起来。也就是值类型和引用类型相互转换的一做桥梁,但是问题也很明显那就是实例会存在在堆栈之前相互copy的问题,会存在一定的性能问题,所以这也一直是一个诟病。
探究本质
上面讲解了关于的概念,接下来咱们就来定义一段代码看看效果,为了方便对比咱们直接对比着看一下
dynamic num = 123;
dynamic str = "a string";
想要看清本质还是要反编译一下生成的结果看一下的,这里我们可以借助或来看下,首先看一下反编译回来的效果
private static void <Main>$(string[] args
{
object num = 123;
object str = "a string";
Console.ReadKey(;
}
因为我是使用的是.net6的顶级声明方式所以会生成方法。不过从反编译的结果就可以看出来,如果还有点怀疑的话可以直接查看生成的代码,还是使用工具
.method private hidebysig static
void '<Main>$' (
string[] args
cil managed
{
// Method begins at RVA 0x2094
// Header size: 12
// Code size: 30 (0x1e
.maxstack 1
.entrypoint
.locals init (
// 这里可以看出声明的num和str变量都是object类型的
[0] object num,
[1] object str
// object obj = 123;
IL_0000: ldc.i4.s 123
// 这里的box说明存在装箱操作
IL_0002: box [System.Runtime]System.Int32
IL_0007: stloc.0
// object obj2 = "a string";
IL_0008: ldstr "a string"
IL_000d: stloc.1
// Console.ReadKey(;
IL_000e: call valuetype [System.Console]System.ConsoleKeyInfo [System.Console]System.Console::ReadKey(
IL_0013: pop
// (no C# code
IL_0014: nop
IL_0015: nop
IL_0016: nop
IL_0017: nop
IL_0018: nop
IL_0019: nop
IL_001a: nop
IL_001b: nop
// }
IL_001c: nop
IL_001d: ret
} // end of method Program::'<Main>$'
通过这里可以看出,既然是object那就可以证实确实是存在装箱操作。
这个其实在微软官方文档Using type dynamic上有说明,大致描述是这样的。
从这里可以看出dynamic表现出来的就是object,只是dynamic会跳过静态类型检查,所以编译的时候不会报错,有错误的话会在运行的时候报错,也就是我们说的是在运行时确定具体操作。这涉及到动态语言运行时,动态语言运行时(DLR是一种运行时环境,可以将一组动态语言服务添加到公共语言运行时(CLR。使用DLR可以轻松开发在.NET上运行的动态语言,并为静态类型语言添加动态特征。
匿名类型
var num = 123;
num = "123"; //报错
如果你是用的集成开发环境的话其实很容易发现,把鼠标放到类型上就会显示变量对应的真实类型。或者可以直接通过看看反编译结果,比如声明了编译完成之后就是
private static void <Main>$(string[] args
{
int num = 123;
Console.ReadKey(;
}
请注意这里并不是而是转换成了具体的类型因为就是int类型的,严谨一点看一下代码
.maxstack 1
.entrypoint
//声明的int32
.locals init (
[0] int32 num
// int num = 123;
IL_0000: ldc.i4.s 123
IL_0002: stloc.0
相信这里就可以看出来了和确实也不是一个层面的东西。var是隐式类型是语法糖为了简化编程体验用的,dynamic则是动态语言运行时技术,编译时转换成object类型,因为在c#上一切都是object,然后再运行时进行具体的操作。