当我正尝试建立一种合适的数据结构用于在Orchard中承载视图模型(view model)——由许多不同的实体毫无约束地构建而成的时候,很快就变得非常明显必须要用一种动态结构。

我们需要的是一分层结构:一个页面可能包涵一个博客文章列表和一些微件(widgets),而每篇博客文章是由许多部件组成的,比如评论,而评论又包涵作者,作者又包涵头像、等级等等。

这就带出了第二个需求:多个实体必须在互不知道对方的情况下共同构建那个对象图(视图模型)。我们预先并不知道这个对象图的形状,且对象图的每个节点都很容易受到后来扩展节点的影响。

现在的问题是使用C#的静态类型来解决这些需求是非常不爽的。

你可以使用类似XML DOM API 的  ChildNodes 和 Attributes 集合 以及 NodeName and Value properties 的方式,而且这确实能够解决问题。

但是我想,绝大多数人都会同意长期以来这种形式的API都是使开发人员痛不欲生的重要原因,因此,除非用枪指着我们的头,否则我们都不想使用这种形式。

这种形式的API之所以极其令人厌烦,最主要的原因是它首先让你获取到元数据,而把获取实际数据推到第二步API,比如Value。

在一个对象图中,你最关心的是节点的值(Value),其次是能够很容易就获得节点的子节点,通过索引或者名字(name)。

老实说,下面两种形式,你更喜欢哪种?

node.Attributes["rating"].Value

  

或者:

node.rating

  

Yeah,我认为是这样。第一种形式感觉好像是在用反射来获得非常简单属性的值。

好吧,现在应该比较清楚C# 中的 XML APIs之所以不爽,是因为静态语言不喜欢不可预知的东西,而想在编译时就知道对象的一切细节。XML APIs 接受预先知道的(节点拥有元数据是固化在结构里的),而把未知的东西推给属性。

换一种说法,元数据应该是对象的一个属性,而最终你得到的真正对象却是元数据结构的一个属性。

在总结之前,我想说一下对象初始化器(object initializers),它已经存在一段时间了,且经常被用来构造模糊可选项的参数,例如:

Html.TextBoxFor(m => m.CurrentUser, new {title = "Please type your user name",style = "float:right;"
})

必须清楚的是,虽然这些匿名对象在创建时非常灵活,但它们是常量,一旦被创建,你就不能再向它们添加新属性或方法,因此,它们不适合我们的用例。

幸运的是,C# 4.0 提供了一个非常好的关键词适合各种各样的情况使用,它就是dynamic。

在part 2,我将展示 Clay (一个由Lou 编写的库)是如何漂亮而优雅地解决我们的问题的。

The Clay library: http://clay.codeplex.com

本贴第二部分:http://aprogrammer.net/2012/08/clay-malleable-c-dynamic-objects-part-2/

原文地址:http://aprogrammer.net/2012/08/clay-malleable-c-dynamic-objects-part-1-why-we-need-it/

转载于:https://www.cnblogs.com/linven/archive/2012/09/05/2672636.html

Clay:易塑的c#动态对象——第一部分:为什么我们需要它相关推荐

  1. 将$type添加到System.Text.Json序列化中,就像Newtonsoft那样用于动态对象属性

    目录 介绍 用户故事5:在System.Text.Json JsonSerializer中支持动态类型 演示项目和测试 修改模型方法 包装方法 总结 Pro Coders团队最近将一个大型项目从New ...

  2. jvm误区--动态对象年龄判定

    学习jvm的人,基本都阅读过上面这段话,这里讲的是动态年龄的判定.对于动态的判定的条件就是相同年龄所有对象大小的总和大于Survivor空间的一半,然后算出的年龄要和MaxTenuringThresh ...

  3. 基于动态代码生成技术的动态对象工厂

    C#中所有的引用类型的实例都需要在运行时动态创建,创建对象实例最常见的办法就是使用new操作符,使用new操作符就需要在编译器明确的知道要创建的对象的类型,如果在编译器并不能明确,就需要用到反射技术, ...

  4. Unity动态对象优化

    对于静态对象,Unity可以使用通过勾选Static,然后让Unity自身进行优化Draw Calls,但是对于动态对象,Unity在这方面没有处理,这就需要我们自己去实现,实现的原理就是首先去遍历每 ...

  5. 【C++】局部变量、全局变量、静态变量与动态对象的性质

    [fishing-pan:https://blog.csdn.net/u013921430转载请注明出处] 概述 局部变量 在一个函数内部定义的变量(包括函数形参)是局部变量. 全局变量 在函数外定义 ...

  6. 使用ExpandoObject将XML转换为动态对象

    目录 介绍 *更新 *更新2 编码 XML示例 用法 注意 介绍 我开始在Internet上寻找一种简单的方法来加载XML文件并将其即时转换为对象.我的目标是为正在处理的Web项目以XML格式动态加载 ...

  7. C++动态空间申请、动态对象(new与delete运算)

    文章目录 一.动态空间申请 二.动态对象的使用 一.动态空间申请 #include <iostream> #include <string.h> #include <st ...

  8. C++类对象成员、动态对象、new、delete运算符申请动态空间(C++初学面向对象)

    文章目录 一.类成员对象 1.类的对象 2.具体参考代码 二.动态对象与new.delete 1.C语言中为类的对象开辟动态空间 2.C++的new开辟动态空间:类型名 *p= new 类型名 3.请 ...

  9. jvm深入理解:内存分配与回收策略(优先在Eden分配、大对象直接进入老年代、长期存活的对象将进入老年代、动态对象年龄判定、空间分配担保)

    出入:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版) Java技术体系的自动内存管理,最根本的目标是自动化地解决两个问题:自动给对象分配内存以及自动回收分配给对象的内存. 象的内存分配,从 ...

最新文章

  1. MySQL数据库中的内置函数
  2. 奥迪坚SVRM(Screen-Voice Recording Manager)录屏软件正式发布
  3. python简单爬虫课题_VS2019python爬虫入门
  4. python如何输出两行_python pandas dataframe拆分行(某些行一行拆成多行)
  5. 50個AJAX Tools and Frameworks
  6. 英伟达正寻求欧盟批准其收购Arm
  7. Spotfire 将字符串日期 转换为 日期格式
  8. UE TurnInPlace 转身动画的解决方案和常见问题
  9. win10开启wifi
  10. ASP.NET内容总结
  11. 强烈推荐:网工利器PNETLab模拟器
  12. android layout.inflater,LayoutInflater.inflate详解
  13. 8086的储存器编址
  14. 即时消息服务器eChat
  15. RobotFramework学习笔记二:遇到Frame框架
  16. 推荐几款jQuery时间轴插件Timeline
  17. html网页制作之细谈HTML前端项目开发过程中的细节及心得_避免入坑
  18. [Video and Audio Data Processing] 截取部分PCM16LE单声道音频采样数据
  19. 喜大普奔——Mapbox GL JS支持多种投影了
  20. React项目-点餐后台管理系统-react框架实现后台管理系统(包含权限处理)--新手入坑必看!(一)

热门文章

  1. python local global_Python 关键字global全局变量详解
  2. redis集群 + 哨兵 + zookeeper_Redis05——Redis Cluster 如何实现分布式集群
  3. python写文件追加 按行追加_你真的会用python进行文件操作吗
  4. form提交php怎么接收不到,php form表单post提交获取不到数据,而使用get提交能获取到数据 的解决办法...
  5. 在c语言中数据类型高低,C语言的数据类型
  6. android edittext的监听,android editText 监听事件
  7. jq如何获取选中option的值_如何用jQuery获得select的值
  8. pcap java_java解析Pcap(io.pkts)
  9. java m2文件放哪里_windows下打开.m2文件夹,没有找到setting.xml
  10. 玻璃质感_photoshop绘制玻璃质感创意图标