当json.js遇见dynamic.net [0]
各位不明真相的围观群众大家好,我承认自己有些标题党了,其实真正的题目应该是‘使用.NET4的dynamic类型与json数据相互映射’ :) (可是这个名字未免也太撮了点)
.NET4之前,数据的序列化都是基于某个具体类型,比如先要定义一个C# class,然后attribute,serializer... javascript则是动态语言,可以动态变化自己的属性(所谓的expando对象)。我们创建一个js对象var obj={}之后可以不断增加新属性,如obj.color='red'。正是由于类型是个弱化的概念,所以js常被称为object-based(基于对象)而非object-oriented(面向对象)。就像鸡不同鸭讲,静态语言与动态语言互动起来是比较吃力的(假设:讲=数据映射)。.NET4推动了对动态语言从底层基础设施(DLR)一直到上层语法建设(dynamic keyword)的支持。接下来的几篇会介绍如何使用.NET4的新特性实现一个能够轻松转换json的mini-library。先来看一下我们的目标:
设计理念
- 大家都很忙,所以整个代码篇幅一定要短。准备将非注释内容控制在150行之内,每个方法在10行之内。这样的话,‘肉’少‘骨骼’清晰,能够很容易的阅读,一扫就能看完,迅速把握重点。
- 为了追求‘高纯度’,异常处理的细活就留给大家去完善了。可能会使用很紧凑的代码风格,比如链式访问,pipeline化操作。
- 能够使C#代码模仿出json的风格,或者说尽量的接近。json数据的语法噪音算是相当小的(js真是了不起,好像语法都没啥变化额)。
- 支持常用的json数据类型,支持理论上的无限层次。
再来看一下几种可能的使用场景(通过愿景来反向设计)
JSON风格
假设定义DJson封装json object{}的处理逻辑,子类DJsonArray:DJson负责json array[]。
public class DJson ...
public class DJsonArray : DJson ...
“Jane今年24岁,有个32的神秘男友Jesse,你看他的手机号多牛X...”将被表示成
dynamic data = DJson.Wrap(new{
name="Jane",
male=false,
age=24,
dob=DateTime.Now,
friend = new{
name="Jesse",
male=true,
age=32,
dob = DateTime.Now},
mobile = new object[]{new[]{86},13888888888},
});
对应的JSON是
{
"name":"Jane",
"male":false,
"age":24,
"dob":"\/Date(1296239796269)\/",
"friend":{
"name":"Jesse",
"male":true,
"age":32,
"dob":
"\/Date(1296239796270)\/"},
"mobile":[[86],13888888888]} //(别问我jesse的手机为什么是个数组)
}
两者形态上已经很接近了,不过json更胜一筹。
动态
js的数组是可以不断添加数据的(这个可以有)
dynamic data = new DJsonArray();
data[0] = new { name = "小朋盂 1号" };
data[1] = new { name = "小朋盂 2号" };
data[2] = new { name = "小朋盂 3号" };
对应的JSON是
[{"name":"小朋盂 1号"},{"name":"小朋盂 2号"},{"name":"小朋盂 3号"}]
JQuery
如果可以用到jquery中那就更棒了。比如让c#写配置信息,为jquery输送炮弹。
$.get("test.php", <%=DJson.Wrap(new { choices = new[] { "Jon", "Susan" } }) %>); //in an aspx file
最终呈现是
$.get("test.php", { "choices": ["Jon", "Susan"]} ); // from http://api.jquery.com/jQuery.get/
可以很方便的解析一些json数据比如twitter的。
我从twitter console那里搞了些public timeline的数据(就是首页的最新话题),不方便FQ的请这里下载。格式大致像这样:
[
{ //status 1
...
"text": "aaaaah liat iklannya nendroidnya black shooter jadi pengeeeeeennnnn",
"id": 31021719573504000,
...
"user": {
...
"name": "Dheena Aoi",
...
"id": 27851528,
...
"location": "\u00dcT: -6.909664,107.667199",
...
},
},
{ //status 2 ...
由JSON转换之后的c#数据应该很容易访问,比如
var json = System.IO.File.ReadAllText("c:/twitter.js");
dynamic statuses = DJson.Parse(json);
for (int i = 0; i < statuses.Length; i++)
{
var status = statuses[i];
Console.WriteLine(" id: {0}\nname: {1}\nfrom: {2}\ntext: {3}\n", status.user.id, status.user.name, status.user.location, status.text);
}
这样就可以打印出所有微博的相关信息了
id: 27851528
name: Dheena Aoi
from: Brittanny Eleven
text: aaaaah liat iklannya nendroidnya black shooter jadi pengeeeeeennnnn
id: 95445857
name: オレンジ
from:
text: デスノートには、「オレンジ 2044年4月10日5:00、「バルス!!」と叫んで死亡
」と記されています。 http://shindanmaker.com/12516 #deathnotter よし、ひこーせき
を用意してくれ。みんな道連れd←
id: 229458542
name: Edris Mathewson
from: Utah
text: :O readings Things One Must Know When Going For Psychic Email Readings ht
tp://bit.ly/fi9ozw
...
在下一篇中我们将walk through所有的关键技术,然后是设计分析,最后是完整的带注版代码。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?