【已更新最新开发文章,点击查看详细】

但是,如果代码无效,则在运行时会捕获到错误。  

dynamic 类型简化了对 COM API(例如 Office Automation API)、动态 API(例如 IronPython 库)和 HTML 文档对象模型 (DOM) 的访问。

因此,dynamic 类型只在编译时存在,在运行时则不存在。

IntelliSense 对 dyn 显示“dynamic” ,对 obj 显示“object” 。

class Program
{
    static void Main(string[] args)
    {
        dynamic dyn = 1;
        object obj = 1;

        System.Console.WriteLine(dyn.GetType());
        System.Console.WriteLine(obj.GetType());
    }
}

C#4.0新增功能01 动态绑定 (dynamic 类型)

C#4.0新增功能01 动态绑定 (dynamic 类型)

输出结果:

C#4.0新增功能01 动态绑定 (dynamic 类型)

若要查看编译时 dyn 与 obj 之间的区别,请在前面示例的声明和 WriteLine 语句之间添加下列两行:

dyn = dyn + 3;
obj = obj + 3;

在编译时不会检查包含 dyn 的表达式,原因是 dyn 的类型为 dynamic

上下文

dynamic 关键字可以直接出现,也可以作为构造类型的组件在下列情况中出现:

  • 下面的类定义在多个不同的声明中使用 dynamic

class ExampleClass
{
    // 动态字段
    static dynamic field;

    // 动态属性
    dynamic prop { get; set; }

    // 动态返回类型和动态类型参数
    public dynamic exampleMethod(dynamic d)
    {
        // 局部动态变量
        dynamic local = "Local variable";
        int two = 2;

        if (d is int)
        {
            return local;
        }
        else
        {
            return two;
        }
    }
}
  • 在显式类型转换中,作为转换的目标类型。

static void convertToDynamic()
{
    dynamic d;
    int i = 20;
    d = (dynamic)i;
    Console.WriteLine(d);

    string s = "Example string.";
    d = (dynamic)s;
    Console.WriteLine(d);

    DateTime dt = DateTime.Today;
    d = (dynamic)dt;
    Console.WriteLine(d);

}
// 输出结果:
// 20
// Example string.
// 7/25/2018 12:00:00 AM
  • 例如,可以在下列表达式中使用 dynamic
int i = 8;
dynamic d;
// 使用 is 操作符
// 在此处动态类型和object相似,The dynamic type behaves like object。除非 somevar 的值为 null ,否则以下表达式将返回true
if (someVar is dynamic) { }

// 使用 as 操作符
d = i as dynamic;

// 使用typeof, 作为构造类型的一部分
Console.WriteLine(typeof(List<dynamic>));

// 以下语句导致编译器错误
//Console.WriteLine(typeof(dynamic));
示例
Main 方法也将编译时类型检查与运行时类型检查进行了对比。
using System;

namespace DynamicExamples
{
    class Program
    {
        static void Main(string[] args)
        {
            ExampleClass ec = new ExampleClass();
            Console.WriteLine(ec.exampleMethod(10));
            Console.WriteLine(ec.exampleMethod("value"));

            // 下面的语句会引发编译器异常。因为 exampleMethod 方法仅包含一个参数
            //Console.WriteLine(ec.exampleMethod(10, 4));

            dynamic dynamic_ec = new ExampleClass();
            Console.WriteLine(dynamic_ec.exampleMethod(10));

            // 因为 dynamic_ec 是 dynamic 类型, 下面的调用(传递了2个参数)不会引发编译器异常。
            // 但是在运行时会引发异常。
            //Console.WriteLine(dynamic_ec.exampleMethod(10, 4));
        }
    }

    class ExampleClass
    {
        static dynamic field;
        dynamic prop { get; set; }

        public dynamic exampleMethod(dynamic d)
        {
            dynamic local = "Local variable";
            int two = 2;

            if (d is int)
            {
                return local;
            }
            else
            {
                return two;
            }
        }
    }
}
// 输出结果:
// Local variable
// 2
// Local variable
使用 dynamic

在运行时,将对存储的信息进行检查,并且任何无效的语句都将导致运行时异常。

例如,如果将鼠标指针放在以下示例中使用的 testSum 上,则 IntelliSense 将显示类型“(局部变量)dynamic testSum” 。

dynamic d = 1;
var testSum = d + 3;

System.Console.WriteLine(testSum);

结果不为 dynamic 的操作包括:

  • 从 dynamic 到另一种类型的转换。
  • 包括类型为 dynamic 的自变量的构造函数调用。

例如,以下声明中 testInstance 的类型为 ExampleClass,而不是 dynamic

var testInstance = new ExampleClass(d);
转换

这样,开发人员将能够在动态行为和非动态行为之间切换。

任何对象都可隐式转换为动态类型,如以下示例所示。

dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();

反之,隐式转换也可动态地应用于类型为 dynamic 的任何表达式。

 

int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;

 

使用类型为 dynamic 的参数重载决策
重载决策之所以会在运行时失败,是因为 d1 的运行时类型为 int,而 exampleMethod2 要求为字符串。
ec.exampleMethod2("a string");

ec.exampleMethod2(d1);
动态语言运行时
动态语言运行时概述。
COM 互操作

命名参数和可选参数的用法。

例如,以下语句对比了在使用 dynamic 类型和不使用 dynamic 类型的情况下如何访问 Microsoft Office Excel 电子表格中的单元格。

// 引入动态之前
((Excel.Range)excelApp.Cells[1, 1]).Value2 = "Name";
Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1];
// 在引入 dynamic 之后,对 value 属性的访问以及到 excel.range 的转换将由运行时 COM 绑定器处理
excelApp.Cells[1, 1].Value = "Name";
Excel.Range range2010 = excelApp.Cells[1, 1];

其他技术请参考

Title 说明
dynamic 描述 dynamic 关键字的用法。
动态语言运行时概述 提供有关 DLR 的概述,DLR 是一种运行时环境,它将一组适用于动态语言的服务添加到公共语言运行时 (CLR)。
演练:创建和使用动态对象 提供有关如何创建自定义动态对象以及创建访问 IronPython 库的对象的分步说明。
如何:通过使用 Visual C# 功能访问 Office 互操作对象 演示如何创建一个项目,该项目使用命名参数和可选参数、dynamic 类型以及可简化对 Office API 对象的访问的其他增强功能。
 
【已更新最新开发文章,点击查看详细】

相关文章:

  • 2022-12-23
  • 2021-12-31
  • 2022-02-09
  • 2022-12-23
猜你喜欢
  • 2021-07-05
  • 2022-01-17
  • 2021-04-28
  • 2021-06-18
  • 2022-12-23
  • 2021-06-09
相关资源
相似解决方案