はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

MessagePack for C#始めました

以前から使おう使おうと思って(実際は使ってみようとして上手くいかなくてを何回か繰り返して、最近の状況で在宅でがっつり集中できるようになったので)いたneueccさんの素敵ライブラリMessagePack-CSharpを既存アプリに組み込むことができました。

github.com

いくつか、DataContractJsonSerializerから書き換えるうえで迷った点がありましたので、まとめておきたいと思います。

MessagePack-CSharpは、非常に高速なC#用シリアライザーです。例えば構造体⇔Byte配列、構造体⇔Byte配列⇔JSON文字列あたりの変換が多数あるような例えば多端末間メッセージ送受信のデータシリアライズなどに適用するとシステム全体の快適さが増すかもしれません。

GitHubで公開されている測定結果を見ると、まさに桁が違う処理速度です。

https://cloud.githubusercontent.com/assets/46207/23835716/89c8ab08-07af-11e7-9183-9e9415bdc87f.png

 

PublicクラスじゃなくてInternalやPrivateなクラスを使う場合

MessagePack-CSharpでは、デフォルトでは指定する構造体はPublicクラスじゃないと実行時エラーが発生します。ネットで検索してみると「Publicクラスでなければならない」という解説もありましたが、本家のneueccさんの説明ではそのような説明がありませんでした。ということはきっとできる方法が用意されているのだろうと考えてドキュメントをもう一度よんでみるた次のような方法の記載をみつけました。やっぱり原典をみないとですね。

InternalやPrivateなクラスを指定したいときは次のようにします。

gist.github.com

 MessagePackSerializerOptions.Standard.WithResolverの引数にStandardResolverAllowPrivate.Instanceを指定してオプション指定をつくり、それをSerialize<プライベートクラス>メソッドの第二引数に指定してあげれば、Privateクラスでも実行時エラーなくシリアライズできます。

便利ですね。

クラスのプロパティ名をJSON文字列の項目名に使う場合

これは簡単で、クラスに[MessagePack.MessagePackObject(true)]属性をつけてあげればOKです。

JSON文字列上の項目名を、クラスのプロパティ名とは別の名前にしたい場合

JSONに指定する項目名が"message-id"などが必要でプロパティ名に指定が難しいような場合には、Key属性で項目名を指定することができます。

まずはダメな例

gist.github.com

クラスに[MessagePack.MessagePackObject(true)]属性をつけて、変更したいプロパティにだけ[MessagePack.Key("message-id")]属性でJSON項目名を指定してみましたが、これでは変更されませんでした。

OKな例。きちんとすべてにKey属性をつけてクラスの属性ではkeyAsPropertyNameをfalseつまり指定しないようにします。

gist.github.com

これでいままで悩んでいた点が解決できたので、リリース版に反映&テストフェーズに入りたいと思います。