C# Clay開源的動態語言dynamic框架,讓您以像JavaScript的方式建立物件!

C# Clay開源的動態語言dynamic框架,讓您以像JavaScript的方式建立物件!

能夠讓我們在不需要定義類別的情況下,就建構出我們想要的物件。

最後更新 2022/7/15 下午9:33
黑哥聊dotNet
預計閱讀 4 分鐘
分類
.NET
標籤
.NET C# 開源

簡介

Clay 非常類似於 ExpandoObject,可以看作是 ExpandoObject 的加強版。它們能夠讓我們在不需要定義類別的情況下,就構建出我們想要的物件。Clay 和 ExpandoObject 相比,提供了更加靈活的語法支援,讓我們像寫 JavaScript 程式碼一樣寫 C# 程式碼,同時還能夠用於構建多層級的複雜物件。

多種方式初始化物件

  1. 最簡單的物件構建和初始化
dynamic New = new ClayFactory();
var person = New.Person();
person.FirstName = "Louis";
person.LastName = "Dejardin";

注意這裡的 Person 並不是一個具體的、實際存在的類別或結構體。我們在不需要定義 Person 類別的情況下,就構建了一個具有 FirstName 和 LastName 屬性的物件。

  1. 使用索引子的方式初始化
var person = New.Person();
person["FirstName"] = "Louis";
person["LastName"] = "Dejardin";
  1. 使用匿名物件的方式實現初始化
var person = New.Person(new {
    FirstName = "Louis",
    LastName = "Dejardin"
});
  1. 使用命名引數方式實現初始化
var person = New.Person(
    FirstName: "Louis",
    LastName: "Dejardin"
);
  1. 鏈式方式初始化
var person = New.Person()
               .FirstName("Louis")
               .LastName("Dejardin");

讀取屬性方式

person.FirstName
person[“FirstName”]
person.FirstName()

上面三種都是存取 FirstName 屬性,它們都是等價的。 多種多樣的初始化物件和讀取屬性的方式,讓 dynamic 變得更加靈活。這些都是 ExpandoObject 所做不到的。

構建神奇的 Array

我們可以建立 JavaScript 風格的 Array:

dynamic New = new ClayFactory();
          var people = New.Array(
              New.Person().FirstName("Louis").LastName("Dejardin"),
              New.Person().FirstName("Bertrand").LastName("Le Roy")
          );
  1. 構建的 Array 具有 Count 屬性
Console.WriteLine("Count = {0}", people.Count);
  1. 可以透過索引存取
Console.WriteLine("people[0].FirstName = {0}", people[0].FirstName);
  1. 支援 foreach 巡覽
foreach (var person in people) {
     Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}
  1. 簡單方便地為物件新增 Array 屬性
person.Aliases("bleroy", "BoudinFatal");

這裡是為 person 這個動態物件新增了一個 Array 屬性,屬性的名字叫 Aliases,所以這裡 Aliases 可以替換成任何名稱,並沒有特定含義。

下面的程式碼和上面的作用是等價的:

persons.Aliases1(new[] {"bleroy", "BoudinFatal"});
  1. Array 中的元素型別是 dynamic,而不是一般型別

因為Array 元素的型別是 dynamic,所以可以有這樣的 Array:

var people = New.Array(
     New.Person().FirstName("Louis").LastName("Dejardin"),
     "Peter"
);

為物件動態新增方法

和 ExpandoObject 一樣,你也可以為其擴充方法,只是方法呼叫的時候,需要多新增一個()。 這可能是 Clay 支援用 () 來存取物件屬性導致的。

var person = New.Pserson();
person.FirstName = "Louis";
person.LastName = "Dejardin";
person.SayFullName = new Func<string, string>(x => person.FirstName + person.LastName + x);

Console.WriteLine(person.SayFullName()(" Here!"));

動態的實現介面

假設我們定義了這個介面,用動態型別建立一個物件,而且這個物件是實作了該介面,這看起來是不是不可完成的任務?Clay 能辦到!

public interface IPerson
{
       string FirstName { get; set; }
       string LastName { get; set; }
}

dynamic New = new ClayFactory();
var people = New.Array(
New.Person().FirstName("Louis").LastName("Dejardin"),
New.Person().FirstName("Bertrand").LastName("Le Roy"));
IPerson lou = people[0];
var fullName = lou.FirstName + " " + lou.LastName;

Clay 應用背景

想要透過構建一個可以自由擴充的、靈活的 dynamic 物件來一勞永逸地解決問題,這就是 Clay 的初衷。

Clay 是一個獨立的開源專案,它無所不能的能力,一定能夠幫助你簡化很多類別定義和反射程式碼。

繼續探索

延伸閱讀

更多文章
同分類 / 同標籤 2026/2/7

AOT使用經驗總結

從專案建立伊始,就應養成良好的習慣,即只要添加了新功能或使用了較新的語法,就及時進行 AOT 發布測試。

繼續閱讀