zoukankan      html  css  js  c++  java
  • 理解C# 4 dynamic(3) – DynamicObject的使用

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

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

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


    Creative Commons License

    本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名justrun(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言

     
    分类: .Net基础
    标签: .Net基础dynamic
  • 相关阅读:
    我所遭遇过的游戏中间件---HumanIK
    我所遭遇过的游戏中间件--Kynapse
    3D屏保:排色榜
    3维DEMO: 抽奖圆盘
    MySQL存储过程中的3种循环
    MyISAM与InnoDB两者之间区别与选择,详细总结,性能对比
    如何执行字符串的PHP代码
    PHP 注册错误和异常处理机制
    Mysql表中唯一编号的分配机制
    装系统w7、ubuntu、centos等系统(一)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3259436.html
Copyright © 2011-2022 走看看