4.3.5 dynamic类型
dynamic类型是C#4.0引入的全新类型,它允许其操作略过编译期类型检查,而在运行时处理。dynamic类型简化了对COM API的调用(例如对Office组件的COM Interop调用),增强了对动态语言的支持(例如IronPython库),简化了对于HTML文档对象模型(DOM)的访问。
dynamic类型在绝大多数情况下和object类型相似,不同点在于,编译器对于包含了dynamic类型的表达式不做进一步解析和类型检查。编译器将这些信息收集到一起,用于在运行时鉴定操作。实际上,dynamic类型的变量被编译成object类型的变量,因此,dynamic类型只存在于编译期,而运行时并不存在,如图4-13所示。
图 4-13 dynamic类型
我们一起来看如下的示例,如代码清单4-12所示。
代码清单4-12 dynamic类型用法
1 using System;
2
3 namespace ProgrammingCSharp4
4{
5 class Program
6{
7 static void Main(string[]args)
8{
9 dynamic dyn=1;
10 object obj=1;
11
12 Console.WriteLine(dyn.GetType());
13 Console.WriteLine(obj.GetType());
14
15//dyn+=1;//编译通过
16//obj+=1;//编译失败
17}
18}
19}
输出结果为:
System.Int32
System.Int32
dyn是dynamic类型变量,在编译期并不知道它的类型,因此,虽然知道1是System.Int32类型,但因dynamic类型变量在编译期并不解析也不做类型检查,因此1的类型信息被编译期收集起来,在运行时根据该信息确定dyn是System.Int32类型的变量,此时dyn就已经不再是dynamic类型的变量了,而是System.Int32类型,因此才会有上述结果。图4-14说明了动态类型在编译期和运行时的类型。
图 4-14 动态类型
我们再做个实验,首先将第15行的注释去除,然后按Shift+F6进行编译,此时应该顺利编译通过;然后将第16行的注释去除[1],再编译,这时会产生一个编译错误:
运算符“+=”无法应用于"object"和"int"类型的操作数
信息显示:“+=”操作符无法应用于object类型和int类型,obj必须强制转换为int型的变量。为什么dyn变量可以呢?因为编译期不对dynamic变量进行类型检查,因此在编译期dyn很容易就过编译器这一关了,到了运行时就更不用说了,那是dynamic的天下,运行时判定dyn变量为System.Int32类型,因此执行"+="运算是完全合法的,关于运算符的详细内容,请参阅第6章。
使用dynamic类型要注意以下几个问题:
❑由于dynamic类型的变量在设计时类型是未知的,因此你无法看到Visual Studio对dynamic类型变量的成员进行自动提示,因为无法提示;
❑由于dynamic类型变量的具体类型要在运行时才能确定,因此你对该变量的成员调用必须是正确的,如果调用了变量没有的属性或方法,将会产生异常。
[1]删掉行首的“//”符号。