上篇文章"理解C# 4 dynamic(2) – ExpandoObject的使用" 了解了ExpandoObject的基本使用。

但ExpandoObject的问题就是它是一个万金油,什么都可以做,但是又都不专注。

使用DynamicObject正好可以解决这个问题。这篇文章介绍DynamicJson是如何继承DynamicObject,包装一个用来处理Json的动态类型。

阅读目录:

一、JS可以灵活处理Json字符串

二、DynamicObject分析

三、DynamicJson代码

四、总结

一,JS可以灵活处理Json字符串

看下面的代码,

var jsonString='{"foo":"json", "bar":100, "nest":{ "foobar":true }}';
var jsonObj = JSON.parse(jsonString);
//接着就能方便的使用
jsonObj.foo
jsonObj.nest.foobar

代码中的jsonObj是动态类型,在.net中,我们也可以反序列化Json,但都需要指定反序列化后的对象类型。

比如使用Json.Net

Newtonsoft.Json.JsonConvert.DeserializeObject(json, typeof(employee))

有没有办法和js一样,反序列化一个dynamic类型来方便的访问Json数据?

下面先来看看DynamicObject如何使用,然后使用DynamicObject来实现我们的想法。

二,DynamicObject分析

DynamicObject有个构造函数,但是protected, 也就是我们没有办法直接实例化来使用它。只能是通过继承来构造DynamicObject的对象。

同时DynamicObject中很很多标记为Virtual的方法,比如:

public virtual bool TryGetMember(GetMemberBinder binder, out object result);

public virtual bool TrySetMember(SetMemberBinder binder, object value);

当我们写个类继承DynamicObject, 这个动态类型类的对象,所具有的特性,就是通过重写这些virtual方法体现出来的。

假设SampleObject 是继承DynamicObject的类,那么

如果我们重写了TryGetMember, 在调用 int number = sampleObject.Number.时,就会调用TryGetMemeber方法来得到返回值。

如果我们重写了TrySetMember,在调用sampleObject.Number = number 时使用,就会调用TrySetMember方法。

了解了DynamicObject, 我们的路线就更加清晰了:

我们要写一个类DynamicJson,继承自DynamicObject

DynamicJson有静态Parse方法,接受一个Json的字符串,返回DynamicJson的对象。

DynamicJson重写TryGetMember方法,这样当访问属性的时候,我们处理,返回正确的值。

三,DynamicJson代码

DynamicJson正是这个思路实现的,下面来分析一下DynamicJson中一些关键代码

Parse静态方法

这段代码非常容易理解,这里将json以xml方式处理,属性变成了xml中的element处理

public static dynamic Parse(string json)
{
using (var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.Unicode.GetBytes(json), XmlDictionaryReaderQuotas.Max))
{
return ToValue(XElement.Load(reader));
}
}

ToValue方法

To value方法根据json反序列化后的xml信息,获取element的type属性,然后根据属性分别处理。

如果是非数组和object类型,就直接返回。

如果是,就返回DynamicJson对象,这样当我们使用对象的属性,就会调用TryGetMember方法

private static dynamic ToValue(XElement element)
{
var type = (JsonType)Enum.Parse(typeof(JsonType), element.Attribute("type").Value);
switch (type)
{
case JsonType.boolean:
return (bool)element;
case JsonType.number:
return (double)element;
case JsonType.@string:
return (string)element;
case JsonType.@object:
case JsonType.array:
return new DynamicJson(element, type);
case JsonType.@null:
default:
return null;
}
}

TryGetMember方法

下面是重写的TryGetMember方法

public override bool TryGetMember(GetMemberBinder binder, out object result)
{ //根据访问的属性,在序列化的xml结构中寻找子element.
var element = xml.Element(binder.Name); if (element == null)
{
result = null;
return false;
} result = ToValue(element);//如果存在该element, 就继续调用ToValue, 如果是普通类型,就能够返回具体的内容,如果是数组或object,就在返回一个DynamicJson对象。
return true;
}

四,总结

DynamicJson的代码实现的功能很多,详细的DynamicJson的代码,可以通过Nuget获取。

通过继承DynamicObject类,实现了非常多的功能类,

有针对Json的DynamicJson,还有针对xml的DynamicXml

使用它们,减少了不必要的类型定义,增加了程序代码的灵活性。

最新文章

  1. HDU 4467 分块
  2. bzoj 3202: [Sdoi2013]项链
  3. css1-css3的那些模糊点
  4. 基于MATLAB的adaboost级联形式的人脸检测实现
  5. 【转】HideInInspector 与SerializeField
  6. PHP遍历数组
  7. jdbc知识问答 分类: 面试 2015-07-10 22:05 5人阅读 评论(0) 收藏
  8. Red5空项目的理解
  9. 人工智能 tensorflow框架-->简介及安装01
  10. java线程池的创建使用
  11. pycharm 的安装及selenium环境的搭建
  12. CentOS 7 系统基础配置
  13. node koa2 玩起来都是中间件啊
  14. springcloud ribbon 客户端负载均衡用法
  15. 一起学Hive——创建内部表、外部表、分区表和分桶表及导入数据
  16. 使用python内置库pytesseract实现图片验证码的识别
  17. HDU 4738 Caocao's Bridges (2013杭州网络赛1001题,连通图,求桥)
  18. erlang 二进制中 拼接 变量或者函数 报错
  19. python之路----TCP与UDP
  20. MapReduce初探

热门文章

  1. HDU5887 Herbs Gathering(2016青岛网络赛 搜索 剪枝)
  2. Python-面向对象(类)二
  3. java内存泄露
  4. HRPlugin For Xcode发布(附源码地址)
  5. 【转】CentOS上部署PPTP和L2TP over IPSec简要笔记
  6. 16-1-27---图解HTTP(02)
  7. 【转】iOS开发 -- Apple Pay
  8. 用wget命令下载jdk
  9. leetcode 199 :Binary Tree Right Side View
  10. nodejs redis 发布订阅机制封装