Clay 是 CodePlex 上的3个开源项目,支持大家创设轻松创设对象,就
JavaScript 或任何动态语言同样不难。Clay 项指标网址是
http://clay.codeplex.com,Clay 近年来重庆大学使用于
Orchard
项目。以下2篇小说解释了Clay的背景:

Clay: malleable C# dynamic objects – part 1: why we need
it

Clay: malleable C# dynamic objects – part
2

以下内容来自上述2篇的简易摘录:

Orchard须求建立一种适于的数据结构用于在Orchard中承载视图模型(view
model)——由许多例外的实体毫无拘束地营造而成的时候,极快就变得十二分显然须要求用一种动态结构。

咱们须要的是一分层结构:一个页面大概包罗多个博客小说列表和局地微件(widgets),而每篇博客作品是由许多部件组成的,比如评论,而评论又包括小编,笔者又包蕴头像、等级等等。

那就带出了第2个供给:八个实体必须在互不知道对方的动静下同步营造那二个指标图(视图模型)。大家事先并不知道那几个目的图的形制,且对象图的各类节点都很简单受到后来扩大节点的熏陶。

近来的标题是使用C#的静态类型来化解那些需求是那几个不爽的。能够运用类似XML
DOM API 的 ChildNodes 和 Attributes 集合 以及 NodeName and Value
properties 的方法,而且这真的能够缓解难点。不过绝抢先八分之四人都会允许长期以来那种样式的API都是使开发人士痛哭流涕的首要原由,因而,除非用枪指着大家的头,不然我们都不想利用那种方式。

那种方式的API之所以极其令人恨到骨头里去,最关键的来头是它首先让您拿走到元数据,而把收获实际多少推到第2步API,比如Value。

前些天理应相比较清楚C# 中的 XML
APIs之所以不爽,是因为静态语言不希罕不可预感的事物,而想在编写翻译时就领会对象的上上下下细节。XML
APIs
接受预先领会的(节点有所元数据是一定在组织里的),而把无人问津的东西推给属性。

换一种说法,元数据应该是指标的2性情质,而最后你获取的的确对象却是元数据结构的三个个性。

C# 4.0 提供了3个分外好的重中之重词适合各类各个的图景接纳,它正是
dynamic

ExpandoObject
实际上是经过一种令人惊讶格局实现的,那使得它卓殊火速。提醒:不是因此字典。又提醒:它是三个百般好的事物。

可是,依照API
可用性原则,它不够大胆,越发是在塑造深层次动态指标图方面它并从未给大家稍事协助。它的表现也正如固定且无法被扩张。

四头,Clay 是可观可扩充的,且专注于深层次对象图的创导和使用。

经过 Clay你能够做的第②件事情就是成立一个大约的对象并在它下边安装属性。在此以前,大家将率先实例化四个给大家提供
语斯洛伐克共和国(The Slovak Republic)语义糖衣的厂子。小编愿意我们能够跳过这一步而采用部分近似静态API的措施(译注:静态工厂方法),不过我们无法。好了,正如你将看到的只需相当小的代价:

dynamic New = ``new ClayFactory();

现行反革命以此“New”对象将援救大家成立新的 Clay对象,正如它的名字所暗示一样(即便那几个名字只是三个常规而已)。

以下是有个别简易且没有稍微新奇的事物:

var person = New.Person();

person.FirstName = ``"Louis"``;

person.LastName = ``"Dejardin"``;

这么些你都能因而 ExpandoObject
来完毕的,但是那里比较有意思的地点是它有八种兑现方式,且开启了钻井潜能之窗。

例如,在 Clay 中,索引语法与天性访问器是相当的,就像是 JavaScript
一样。当您在写代码通过名字去访问叁特性质,而以此特性的名字在编写翻译时刻又是大惑不解的时候,那就不行实惠了:

var person = New.Person();

person[``"FirstName"``] = ``"Louis"``;

person[``"LastName"``] = ``"Dejardin"``;

但还不止于此,你仍是能够将品质作为链式设置器来选取,像 jQuery那样:

var person = New.Person()

`.FirstName(“Louis”`)

`.LastName(“Dejardin”`);

抑或,如若您喜爱,你还是能流传二个匿名对象:

var person = New.Person(``new {

`FirstName =“Louis”`,

`LastName =“Dejardin”`

});

更为好的是,Clay 还是能分晓命名参数,大家得以这么写:

var person = New.Person(

`FirstName:“Louis”`,

`LastName:“Dejardin”`

);

一句话来说,你能够运用很各种方法来设置属性和开始化 Clay 对象。

正如你所料,获取属性值也有二种形式且它们都是格外效果的:

person.FirstName

person[``"FirstName"``]

person.FirstName()

您也得以制造 JavaScript-style 数组:

var people = New.Array(

`New.Person().FirstName(“Louis”).LastName(“Dejardin”`),

`New.Person().FirstName(“Bertrand”).LastName(“Le Roy”`)

);

那种措施开创的数组也是二个全部的 Clay对象,那代表你能够在运行时对它添加属性。

下一场,如果您想掌握数组里的总项数,或然取得数组第二项的 FirstName
属性值,你能够如此:

people.Count

people[0].FirstName

当您想在三个业已存在的 Clay 对象上创办多个数组属性,那也分外不难:

person.Aliases(``"bleroy"``, ``"BoudinFatal"``);

如果有多于3个参数被传出,Clay就会以为你正在开端化的那一个性格是数组。但是一旦唯有0或一个参数,你只虽显式地传出三个数组
(CL奥迪Q3 or Clay):

person.Aliases(``new``[] {``"Lou"``});

相比较 CL奥迪Q3 数组,Clay 数组能动态增进:

person.Aliases.Add(``"loudej"``);

再正是,它们也能够响应一些艺术调用,如 AddRange, Insert, Remove, RemoveAt,
Contains, IndexOf, or CopyTo 。

综合起来,我们就足以由此一种十三分简短而又不无表现力的语法来创建三个格外复杂的靶子图:

var directory = New.Array(

``New.Person(

`FirstName:“Louis”`,

`LastName:“Dejardin”`,

`Aliases:new[] {“Lou”`}

``),

``New.Person(

`FirstName:“Bertrand”`,

`LastName:“Le Roy”`

`).Aliases(“bleroy”,“boudin”`),

``New.Person(

`FirstName:“Renaud”`,

`LastName:“Paquay”`

`).Aliases(“Your Scruminess”,“Chef”`)

).Name(``"Some Orchard folks"``);

最后一点自个儿想注脚的是,Louis第②遍呈现它给自己看的时候,小编以为确实12分优雅和诧异。

想像一下您有三个CL本田UR-V接口供给贯彻,例如:

public interface IPerson {

`string` `FirstName {get;set`; }

`string` `LastName {get;set`; }

}

可是你想使用叁个 Clay 对象,比如在地点定义的数组 persons
中一个成分。是的,你能够那样:

IPerson lou = people[0];

var fullName = lou.FirstName + ``" " + lou.LastName;

那里最尤其的是 lou 是多少个那一个合法的静态类型 CLOdyssey变量,你将取得任何智能感知和编写翻译时检查。固然大家一向不写过完成那几个接口的有血有肉项目,但它正是一个贯彻了
IPerson 的对象。

可以实现那样不堪设想的机能,是因为 Clay重写了转移操作符,并为这几个接口创制了二个动态代理(使用
Castle),这几个动态代理再托付成员调用给
Clay 对象。

因此,那是1个当真 CLLAND 类型,但它是在运行时被扭转的。

那正是使您可见写以下代码的:

foreach``(var person ``in directory) {

``Trace.Write(person.FirstName);

}

此地发出了事情是: “directory” Clay 数组被转换到三个IEnumerable,而有所相应的不二法门都经过 Clay 动态数组对象完成。

有关作品:

信赖 Clay 编写 难以想象 的 c#
代码

http://weblogs.asp.net/bleroy/archive/tags/Clay/default.aspx

相关文章

网站地图xml地图