理解C# 4 dynamic(3) – DynamicObject的使用

上篇文章"理解C# 4 dynamic(2) – ExpandoObject的使用" 了解了xpandoObject的基本使用。但ExpandoObject的问题就是它是一个万金油,什么都可以做,但是又都不专注。使用DynamicObject正好可以解决这个问题。这篇文章介绍DynamicJson是如何继承DynamicObject,包装一个用来处理Json的动态类型。

一,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(1) - var, object, dynamic的区别以及dynamic的使用

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

原文地址:http://www.cnblogs.com/JustRun1983/p/3258540.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/325859.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jsx中的注释的写法

{}表示里面要写js语句 js语句里面的注释为/**/

Java中的位移运算

位移运算符 左移 “a<<b”将二进制形式的a逐位左移b位&#xff0c;最低位空出来的b位补0。 带符号右移 “a>>b”将二进制形式的a逐位右移b位&#xff0c;最高位空出来的b位补原来的符号位。 无符号右移 “a>>>b”将二进制形式的a逐位右移b位&#xff0c…

sqlserver存储过程

一、存储过程 1.预先存储好的sql程序&#xff0c;保存在sqlserver中&#xff0c;通过名称和参数执行。 2.存储过程中可以包含&#xff1a;insert语句&#xff0c;update语句&#xff0c;delete语句&#xff0c;select语句&#xff0c;逻辑控制语句以及变量。 二、存储过程的优点…

微软正在用实际行动告诉你: 拥抱开源,微软是认真的

2017年4月19日至20日&#xff0c;由工业和信息化部指导、中国信息通信研究院主办、云计算开源产业联盟承办的"全球云计算开源峰会"在国家会议中心举行。微软.NET CORE开发平台荣获由峰会云计算开源产业联盟(OSCAR) 评选出的“尖峰开源技术”奖&#xff0c;标志着国内…

初识Windows程序

一、创建windows应用程序的步骤 1.新建项目 2.项目类型为C#项目 3.模板为windows应用窗体 二、构造方法&#xff1a; 语法&#xff1a;访问修饰符 类名(){} 三、命名规范前缀&#xff1a; 标签–>lable–>lbl 文本框–>textbox–>txt 组合框–>combobox–>cb…

React不提交表单并且获取表单中的数据

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>1_非受控组件</title> </head> <body><!-- 准备好一个“容器” --><div id"test"></div><!-- 引入…

Java中数组的赋值方式

方法一&#xff1a; 使用默认是初始值来初始化数组中的每一个元素 语法&#xff1a;数组元素类型 [ ] 数组名 new 数组元素类型[数组中元素的个数&#xff08;数组的长度&#xff09;] int [ ] number new int [10]; 方法二&#xff1a; 先赋值&#xff0c;然后在赋予默认的初…

分布式系统Paxos算法

转载自 分布式系统Paxos算法 这是一个有关Paxos算法非常形象的讲解与示范。Paxos是能够基于一大堆完全不可靠的网络条件下却能可靠确定地实现共识一致性的算法。也就是说&#xff1a;它允许一组不一定可靠的处理器&#xff08;服务器&#xff09;在某些条件得到满足情况下就能…

winform实现简单的计算器V1版本

最近在整winform程序&#xff0c;就做了些简单的案例出来&#xff0c;比如说下面的这个计算器&#xff1a; 这个的实现方式还是比较简单的。 首先按照图中的界面从工具箱中拉出来一个窗体&#xff0c;其中的显示结果“86”“1849”也是lable控件&#xff0c;最后放一个计算的…

用.netcore写一个简单redis驱动,调试windows版本的redis

1. 下载windows版本的redis 2.开发环境vs2017 新建一个 .net core控制台。 private static Socket socket new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); private static BufferedStream buffer null; socket.NoDelay true; s…

JAVA封装性

1、封装性的概念 &#xff08;1&#xff09;封装性是面向对象思想的三大特征之一 &#xff08;2&#xff09;封装就是隐藏实现细节&#xff0c;仅对外提供访问接口。 &#xff08;3&#xff09;属性的封装、方法的封装、类的封装、组件的封装、模块化的封装、系统级封装。 2、封…

分布式系统的Raft算法

转载自 分布式系统的Raft算法 过去, Paxos一直是分布式协议的标准&#xff0c;但是Paxos难于理解&#xff0c;更难以实现&#xff0c;Google的分布式锁系统Chubby作为Paxos实现曾经遭遇到很多坑。 来自Stanford的新的分布式协议研究称为Raft&#xff0c;它是一个为真实世界应…

React类里面能写的东西

1.一般方法 2.赋值语句 3.静态方法 4.构造函数

构建布局良好的Windows程序

一、菜单栏控件MenuStrip&#xff1a; 1.name:菜单栏控件的名称 2.items:在菜单中显示项的集合 3.Text:与菜单相关联的文本 二、工具栏控件ToolStrip&#xff1a; 1.DisplayStyle:设置文本的显示方式&#xff0c;ImageAndText,显示图像和文本 2.Image:显示的图片 3.Text:显示的…

拆分:分解单块系统——《微服务设计》读书笔记

通常&#xff0c;我们可能已有有一个巨大的单块系统&#xff0c;如何实现微服务&#xff0c;我们需要把它分解。 从哪里开始拆分&#xff1a;接缝 接缝&#xff1a;从接缝处可以抽取相对独立的一部分代码&#xff0c;对这部分代码的修改不会影响系统的其他部分。这些接缝就可以…

winfrom实现简单计算器V2版本

前面&#xff0c;使用winform实现了个简单的计算器&#xff0c;今天&#xff0c;再来给大家看一个稍微复杂点的计算器&#xff0c;效果图如下&#xff1a; 包括归零&#xff0c;退格&#xff0c;加减乘除都已经实现&#xff0c;如果想要继续扩展的可以在稍微改改即可。 现在看…

ACID中C与CAP定理中C的区别

转载自 ACID中C与CAP定理中C的区别 ACID和CAP定理中都有C&#xff0c;代表Consistent一致性&#xff0c;很多人容易将这两个C混为一谈&#xff0c;其实这两个一致性是有区别的。 事务的定义是一系列操作要么全部成功&#xff0c;要么全部不成功&#xff0c;数据库的事务机制是…

单例模式——Java

单例模式&#xff08;Singleton Pattern&#xff09;是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被创建…

winform通过ListView绑定数据库数据源

来&#xff0c;我们开始拉窗体&#xff0c;和我一样的这个就可以&#xff1a; 很简单&#xff0c;在窗体里面只放一个ListView控件即可&#xff0c;然后点击ListView的属性Columns 分别在Text里面写用户名和密码&#xff0c;点击确定。 然后设置显示视图View为Details&…