上篇文章"理解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

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

理解C# 4 dynamic(3) – DynamicObject的使用的更多相关文章

  1. 理解C# 4 dynamic(4) – 让人惊艳的Clay

    Clay非常类似于ExpandoObject, 可以看做是ExpandoObject的加强版. 它们能够让我们在不需要定义类的情况下,就构建出我们想要的对象.Clay和ExpandoObject相比, ...

  2. 理解C# 4 dynamic(4) – 让人惊艳的Clay(转)

    作者:Justrun名字来自<阿甘正传>,是希望自己能够更更傻一点. link: http://www.cnblogs.com/JustRun1983/p/3529157.html   理 ...

  3. 理解C# 4 dynamic(2) – ExpandoObject的使用

    ExpandoObject的使用非常简单,很容易入手.上一篇里面已经有详细的介绍了,可以看这里(理解C# 4 dynamic(1) - var, object, dynamic的区别以及dynamic ...

  4. 理解C# 4 dynamic(1) - var, object, dynamic的区别以及dynamic的使用

    阅读目录: 一. 为什么是它们三个 二. 能够任意赋值的原因 三. dynamic的用法 四. 使用dynamic的注意事项 一. 为什么是它们三个? 拿这三者比较的原因是它们在使用的时候非常相似.你 ...

  5. [转]理解C# 4 dynamic(1) - var, object, dynamic的区别以及dynamic的使用

    阅读目录: 一. 为什么是它们三个 二. 能够任意赋值的原因 三. dynamic的用法 四. 使用dynamic的注意事项 一. 为什么是它们三个? 拿这三者比较的原因是它们在使用的时候非常相似.你 ...

  6. var, object, dynamic的区别以及dynamic的使用

    var, object, dynamic的区别以及dynamic的使用 理解C# 4 dynamic(1) - var, object, dynamic的区别以及dynamic的使用 2013-06- ...

  7. C#中的var和dynamic

    在理解var和dynamic关键字之前,让我们先了解一下编程语言的类别. C#中有两类编程语言: 静态类型语言类别 动态语言类别 静态类型语言 静态类型语言也被称为强类型语言.所谓强类型语言,通俗的讲 ...

  8. 算法-动态规划 Dynamic Programming--从菜鸟到老鸟

    算法-动态规划 Dynamic Programming--从菜鸟到老鸟      版权声明:本文为博主原创文章,转载请标明出处. https://blog.csdn.net/u013309870/ar ...

  9. [LeetCode] 329. Longest Increasing Path in a Matrix_Hard tag: Dynamic Programming, DFS, Memoization

    Given an integer matrix, find the length of the longest increasing path. From each cell, you can eit ...

随机推荐

  1. [MS SQL Server]SQL Server如何开启远程访问

    在日常工作中,经常需要连接到远程的MS SQL Server数据库中.当然也经常会出现下面的连接错误. 解决方法: 1. 设置数据库允许远程连接,数据库实例名-->右键--->属性---C ...

  2. MIT 6.828 JOS学习笔记13 Exercise 1.10

    Lab 1 Exercise 10 为了能够更好的了解在x86上的C程序调用过程的细节,我们首先找到在obj/kern/kern.asm中test_backtrace子程序的地址, 设置断点,并且探讨 ...

  3. 解决谷歌浏览器中的input背景色默认是黄色

    input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset !important; }

  4. LINUX 常用命令 ps 详解

    ps常用命令 ps -u ceshi 查看特定用户(ceshi)进程的情况 ps aux | grep nginx 查找nginx的进程 pa -ef | grep nginx 查找nginx的进程 ...

  5. vuejs的使用方法

    1.安装webpack打包工具 npm install -g webpack 2.安装vue客户端 npm install -g vue-cli 3.初始化项目 vue init webpack de ...

  6. 国外程序员整理的Java资源大全分享

    Java 几乎是许多程序员们的入门语言,并且也是世界上非常流行的编程语言.国外程序员 Andreas Kull 在其 Github 上整理了非常优秀的 Java 开发资源,推荐给大家. 译文由 Imp ...

  7. startssl申请配置免费https证书

    之前给业务配置都是在沃通上申请免费证书,而后通过反向代理层的Nginx进行https认证. 今天来了个新需求,要求域名直接解析至阿里云SLB.https配置需要通过阿里云的控制台部署这倒无所谓,只是在 ...

  8. strong,weak, retain, assign的区别

    strong,weak, retain, assign的区别 strong与weak是由ARC新引入的对象变量属性 xcode 4.2(ios sdk4.3和以下版本)和之前的版本使用的是retain ...

  9. 一些ES5的操作数组的方法

    在ES5规范中新增了不少操作数组的方法,特此罗列一下以备使用 1. forEach循环 有点类似jQuery的each循环 [12,23,36,4,5].forEach(function(v,k){ ...

  10. Docker学习笔记第一章:补充

    只记得学习后面的命令,忘记整理一些概念性的东西了,只能做个补充了=.= Docker虽然也是一种虚拟技术,但是不同于虚拟机的概念.Docker是一种以容器为主的技术,容器运行不需要模拟层(emulat ...