概要
Clay は ExpandoObject と非常に似ており、ExpandoObject の強化版と見なすことができます。これらを使用すると、クラスを定義しなくても、必要なオブジェクトを構築できます。Clay は ExpandoObject と比較して、より柔軟な構文をサポートし、JavaScript コードのように C# コードを記述できるだけでなく、複数階層の複雑なオブジェクトを構築することもできます。

複数の方法でオブジェクトを初期化
- 最もシンプルなオブジェクト構築と初期化
dynamic New = new ClayFactory();
var person = New.Person();
person.FirstName = "Louis";
person.LastName = "Dejardin";
注意 ここでの Person は、具体的な実際のクラスや構造体ではありません。Person クラスを定義しなくても、FirstName と LastName プロパティを持つオブジェクトを構築しています。
- インデクサを使用した初期化
var person = New.Person();
person["FirstName"] = "Louis";
person["LastName"] = "Dejardin";
- 匿名オブジェクトを使用した初期化
var person = New.Person(new {
FirstName = "Louis",
LastName = "Dejardin"
});
- 名前付き引数を使用した初期化
var person = New.Person(
FirstName: "Louis",
LastName: "Dejardin"
);
- チェーン方式での初期化
var person = New.Person()
.FirstName("Louis")
.LastName("Dejardin");
プロパティの読み取り方法
person.FirstName
person[“FirstName”]
person.FirstName()
上記の3つはすべて 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")
);
- 構築された Array には Count プロパティがあります
Console.WriteLine("Count = {0}", people.Count);
- インデックスでアクセス可能
Console.WriteLine("people[0].FirstName = {0}", people[0].FirstName);
- foreach でループ可能
foreach (var person in people) {
Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}
- オブジェクトに簡単に Array プロパティを追加
person.Aliases("bleroy", "BoudinFatal");
ここでは person という動的オブジェクトに Array プロパティを追加しています。プロパティ名は Aliases なので、Aliases は任意の名前に置き換え可能で、特定の意味はありません。
以下のコードも同等の動作をします:
persons.Aliases1(new[] {"bleroy", "BoudinFatal"});
- 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 は独立したオープンソースプロジェクトであり、その万能な能力は、多くのクラス定義やリフレクションコードを簡略化するのに役立つことでしょう。