动态

dynamic 关键字与动态类型对象一起使用 。声明为 dynamic 的对象放弃编译时静态检查,而是在运行时进行评估。

using System;
using System.Dynamic;

dynamic info = new ExpandoObject();
info.Id = 123;
info.Another = 456;

Console.WriteLine(info.Another);
// 456

Console.WriteLine(info.DoesntExist);
// Throws RuntimeBinderException

以下示例将 dynamic 与 Newtonsoft 的库 Json.NET 一起使用,以便从反序列化的 JSON 文件中轻松读取数据。

try
{
    string json = @"{ x : 10, y : ""ho""}";
    dynamic deserializedJson = JsonConvert.DeserializeObject(json);
    int x = deserializedJson.x;
    string y = deserializedJson.y;
    // int z = deserializedJson.z; // throws RuntimeBinderException
}
catch (RuntimeBinderException e)
{
    // This exception is thrown when a property
    // that wasn't assigned to a dynamic variable is used
}

动态关键字存在一些限制。其中之一是使用扩展方法。以下示例为 string:SayHello 添加扩展方法。

static class StringExtensions
{
    public static string SayHello(this string s) => $"Hello {s}!";
}

第一种方法是像往常一样调用它(如字符串):

var person = "Person";
Console.WriteLine(person.SayHello());

dynamic manager = "Manager";
Console.WriteLine(manager.SayHello()); // RuntimeBinderException

没有编译错误,但在运行时你得到了一个 RuntimeBinderException。解决方法是通过静态类调用扩展方法:

var helloManager = StringExtensions.SayHello(manager);
Console.WriteLine(helloManager);