理解C# 4 dynamic(3) – DynamicObject的使用
上篇文章"理解C# 4 dynamic(2) – ExpandoObject的使用" 了解了xpandoObject的基本使用。但ExpandoObject的問題就是它是一個(gè)萬(wàn)金油,什么都可以做,但是又都不專注。使用DynamicObject正好可以解決這個(gè)問題。這篇文章介紹DynamicJson是如何繼承DynamicObject,包裝一個(gè)用來(lái)處理Json的動(dòng)態(tài)類型。
一,JS可以靈活處理Json字符串
看下面的代碼,
var jsonString='{"foo":"json", "bar":100, "nest":{ "foobar":true }}';var jsonObj = JSON.parse(jsonString);//接著就能方便的使用jsonObj.foo jsonObj.nest.foobar代碼中的jsonObj是動(dòng)態(tài)類型,在.net中,我們也可以反序列化Json,但都需要指定反序列化后的對(duì)象類型。
比如使用Json.Net
Newtonsoft.Json.JsonConvert.DeserializeObject(json, typeof(employee))有沒有辦法和js一樣,反序列化一個(gè)dynamic類型來(lái)方便的訪問Json數(shù)據(jù)?
下面先來(lái)看看DynamicObject如何使用,然后使用DynamicObject來(lái)實(shí)現(xiàn)我們的想法。
?
二,DynamicObject分析
DynamicObject有個(gè)構(gòu)造函數(shù),但是protected, 也就是我們沒有辦法直接實(shí)例化來(lái)使用它。只能是通過繼承來(lái)構(gòu)造DynamicObject的對(duì)象。
?
同時(shí)DynamicObject中很很多標(biāo)記為Virtual的方法,比如:
public virtual bool TryGetMember(GetMemberBinder binder, out object result);public virtual bool TrySetMember(SetMemberBinder binder, object value);
當(dāng)我們寫個(gè)類繼承DynamicObject, 這個(gè)動(dòng)態(tài)類型類的對(duì)象,所具有的特性,就是通過重寫這些virtual方法體現(xiàn)出來(lái)的。
?
假設(shè)SampleObject 是繼承DynamicObject的類,那么
如果我們重寫了TryGetMember, 在調(diào)用 int number = sampleObject.Number.時(shí),就會(huì)調(diào)用TryGetMemeber方法來(lái)得到返回值。
如果我們重寫了TrySetMember,在調(diào)用sampleObject.Number = number 時(shí)使用,就會(huì)調(diào)用TrySetMember方法。
?
了解了DynamicObject, 我們的路線就更加清晰了:
我們要寫一個(gè)類DynamicJson,繼承自DynamicObject
DynamicJson有靜態(tài)Parse方法,接受一個(gè)Json的字符串,返回DynamicJson的對(duì)象。
DynamicJson重寫TryGetMember方法,這樣當(dāng)訪問屬性的時(shí)候,我們處理,返回正確的值。
三,DynamicJson代碼
DynamicJson正是這個(gè)思路實(shí)現(xiàn)的,下面來(lái)分析一下DynamicJson中一些關(guān)鍵代碼
Parse靜態(tài)方法
這段代碼非常容易理解,這里將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方法根據(jù)json反序列化后的xml信息,獲取element的type屬性,然后根據(jù)屬性分別處理。
如果是非數(shù)組和object類型,就直接返回。
如果是,就返回DynamicJson對(duì)象,這樣當(dāng)我們使用對(duì)象的屬性,就會(huì)調(diào)用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)
{
? ? //根據(jù)訪問的屬性,在序列化的xml結(jié)構(gòu)中尋找子element.
? ? var element = xml.Element(binder.Name);
? ? if (element == null)
? ? {
? ? ? ? ?result = null;
? ? ? ? ?return false;
? ? }
? ? ?result = ToValue(element);//如果存在該element, 就繼續(xù)調(diào)用ToValue, 如果是普通類型,就能夠返回具體的內(nèi)容,如果是數(shù)組或object,就在返回一個(gè)DynamicJson對(duì)象。
? ? ?return true;
}
四,總結(jié)
DynamicJson的代碼實(shí)現(xiàn)的功能很多,詳細(xì)的DynamicJson的代碼,可以通過Nuget獲取。通過繼承DynamicObject類,實(shí)現(xiàn)了非常多的功能類,有針對(duì)Json的DynamicJson,還有針對(duì)xml的DynamicXml,使用它們,減少了不必要的類型定義,增加了程序代碼的靈活性。
相關(guān)文章:
理解C# 4 dynamic(1) - var, object, dynamic的區(qū)別以及dynamic的使用
理解C# 4 dynamic(2) – ExpandoObject的使用
原文地址:http://www.cnblogs.com/JustRun1983/p/3258540.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的理解C# 4 dynamic(3) – DynamicObject的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务的协作:服务间的消息传递——《微服务
- 下一篇: 微软正在用实际行动告诉你: 拥抱开源,微