動態

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);