profile
Clay is very similar to ExpandoObject and can be seen as an enhanced version of ExpandoObject. They allow us to build the objects we want without having to define classes. Compared with ExpandoObject, Clay provides more flexible syntax support, allowing us to write C#code like javascript code, while also being able to build complex objects at multiple levels.

Multiple ways to initialize objects
- The simplest object construction and initialization
dynamic New = new ClayFactory();
var person = New.Person();
person.FirstName = "Louis";
person.LastName = "Dejardin";
** Note ** The Person here is not a specific, actual class or structure. We built an object with the FirstName and LastName attributes without having to define the Person class.
- Initialization using an indexer
var person = New.Person();
person["FirstName"] = "Louis";
person["LastName"] = "Dejardin";
- Use anonymous objects to achieve initialization
var person = New.Person(new {
FirstName = "Louis",
LastName = "Dejardin"
});
- Use named parameters to achieve initialization
var person = New.Person(
FirstName: "Louis",
LastName: "Dejardin"
);
- Chain initialization
var person = New.Person()
.FirstName("Louis")
.LastName("Dejardin");
Read attribute method
person.FirstName
person[“FirstName”]
person.FirstName()
The above three are all for accessing the FirstName attribute, and they are all equivalent.
多种多样的初始化对象和读取属性的方式,让dynamic变得更加灵活. 这些都是ExpandoObject所做不到的。
Build the Magic Array
We can create a Javascript style Array:
dynamic New = new ClayFactory();
var people = New.Array(
New.Person().FirstName("Louis").LastName("Dejardin"),
New.Person().FirstName("Bertrand").LastName("Le Roy")
);
- Constructed Array with Count attribute
Console.WriteLine("Count = {0}", people.Count);
- Accessible through index
Console.WriteLine("people[0].FirstName = {0}", people[0].FirstName);
- Support foreach traversal
foreach (var person in people) {
Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}
- Simply and easily add Array properties to objects
person.Aliases("bleroy", "BoudinFatal");
这里是为person这个动态对象添加了一个Array属性,属性的名字叫Aliases, 所以这里Aliases可以替换成任何名称,并没有特定含义。
The following code is equivalent to the above function:
persons.Aliases1(new[] {"bleroy", "BoudinFatal"});
- The element type in Array is dynamic, not normal
因为Array元素的类型是dynamic, 所以可以有这样的 Array:
var people = New.Array(
New.Person().FirstName("Louis").LastName("Dejardin"),
"Peter"
);
Dynamically add methods to objects
和 ExpandoObject 一样,你也可以为其扩展方法,只是方法调用的时候,需要多添加一个().
This may be caused by Clay's support for using () to access object properties.
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!"));
Dynamic implementation interface
Suppose we define this interface, create an object with dynamic typing, and the object implements the interface, does this seem like an impossible task? Clay can do it!
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 application background
想通过一种构建一个可以自由扩展的,灵活的dynamic对象来一劳永逸的解决问题,这就是 Clay 的初衷。
Clay is an independent open source project with its all-powerful ability to help you simplify many class definitions and reflection code.