dynamicC# 类型系统中引入了一种新的伪类型。它被视为System.Object,但此外,任何成员访问(方法调用、字段、属性或索引器访问,或委托调用)或运算符对此类类型的值的应用都是允许的,无需任何类型检查,及其解析被推迟到运行时。这被称为鸭子类型或后期绑定。例如:
// 返回任何对象的 Length 属性或字段的值 int GetLength(dynamic obj) { return obj.Length; } GetLength("Hello, world"); // 一个字符串有一个 Length 属性, GetLength(new int[] { 1, 2, 3 }); // 数组也是如此, GetLength(42); // 但不是整数 - 将抛出异常 // 在运行时的 GetLength 方法中
在这种情况下,使用动态类型来避免更冗长的反射。它仍然在幕后使用反射,但由于缓存,它通常更快。
此功能主要针对与动态语言的互操作性。
// 初始化引擎并执行文件 var runtime = ScriptRuntime.CreateFromConfiguration(); dynamic globals = runtime.Globals; runtime.ExecuteFile("Calc.rb"); // 使用 Ruby 中的 Calc 类型 dynamic calc = globals.Calc.@new(); calc.valueA = 1337; calc.valueB = 666; dynamic answer = calc.Calculate();
动态类型甚至在大多数静态类型的代码中也有应用,例如它可以在不实现访问者模式的情况下进行双重调度。