理解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跨平臺或掃描二維碼關注
總結
以上是生活随笔為你收集整理的理解C# 4 dynamic(3) – DynamicObject的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务的协作:服务间的消息传递——《微服务
- 下一篇: c# char unsigned_dll