TERRYのブログ

最近は競技プログラミングにお熱。

Sponsored Link

dynamicなSystem.JsonもといJsonValueを使ってみる

最近何かとよく目にするJSON(私だけですかね)。
今までC#でJSONを扱うときはneue ccさんのDynamicJsonを使っていたのですが、なにやらSilverlightにはSystem.Jsonなるものがあるらしいのでこちらも使ってみることに。
ただ.Net 4.5だとどうも入ってないみたい?なので調べてみるとNuGet上にJsonValueという名前で公開されているそうで、こちらを導入してみました。

導入

GUIの方から入れようと思ったのですが見当たらないのでコンソールから入れることに。
Visual Studio 2013のメニューからツール>ライブラリ パッケージ マネージャー>パッケージ マネージャー コンソールを選択して、出てきたコンソール画面に

PM> Install-Package JsonValue -Version 0.6.0

と打てばおしまい。

使ってみる

こんなオブジェクトがあったとして、

{
 "id":20,
 "name":"味噌",
 "price":250
}

こんな感じでコードを書くと、

using System;
using System.Json;

string data = @"{
     ""id"":20,
     ""name"":""味噌"",
     ""price"":250
 }";

dynamic json = JsonObject.Parse(data).AsDynamic();

Console.WriteLine(json.price);

こんな風に出力してくれます。

250

面倒なクラス定義なんかはいりません。dynamic便利!
JsonObject.Parseで読み込んだJsonObjectに対してAsDynamic()してあげるとdynamic型として扱えるようになる、といった感じらしいですね。もしデータがstreamだったときはJsonObject.Parse()の代わりにJsonObject.Load()を使ってあげるといい感じです。

dynamicって最初何に使うんだろうと思ってたんですがこういう外部のゆるい感じのデータと絡ませるとすごく便利だなあと感じました。IntelliSenseは効きませんが(当然)。
プログラミング始めた頃からIntelliSenseにおんぶにだっこなゆとりプログラマーとしてはコード補完が出てこないだけで死にそうになりますね……。どれだけ頼り切ってたか実感します。


他にも、例えば

{"items":[
  {
    "id":20,
    "name":"味噌",
    "price":250
  },
  {
    "id":21,
    "name":"塩",
    "price":150
  },
  { 
    "id":22,
    "name":"砂糖",
    "price":210
  }
]}"

こんなJSONデータに対して

string data = @"{
""items"":[
  {
    ""id"":20,
    ""name"":""味噌"",
    ""price"":250
  },
  {
    ""id"":21,
    ""name"":""塩"",
    ""price"":150
  },
  { 
    ""id"":22,
    ""name"":""砂糖"",
    ""price"":210
  }
]}";
            
dynamic json = JsonObject.Parse(data).AsDynamic();

foreach (var item in json.items)
{
    Console.WriteLine("{0}: {1:c}", item.name.Value, item.price.Value);
}

Console.WriteLine("Total: {0:c}", (json.items as IEnumerable<JsonValue>).Sum(item => item.AsDynamic().price.Value));

と書くと

味噌: \250
塩: \150
砂糖: \210
Total: \610

てな感じで処理してくれます。
わざわざitem.name.Valueみたいにやってるのはitem.nameはあくまでJsonValue型なのでそこからstring型なりint型なりといった中身を取り出してやるためです。

しかしSum()周りが汚いですね……。何か上手い方法はないかなあ。

ともあれdynamicでJSONを扱ってみました、というお話でした。