[C#]MemoryPackを使ってみたい5 - VersionTolerant
11/10にver1.5.0がリリースされました。
MemoryPackを使ってみたい1 - 基本 の注意事項で、フィールドに関する制限がいくつかありましたが、それを緩和する機がはいりました。
GenerateType.VersionTolerant
MemoryPackable
属性をつけるときに、MemoryPackable(GenerateType.VersionTolerant)
とGenerateTypeを指定して、各フィールドにMemoryPackOrder
をちゃんとつけます。
[MemoryPackable(GenerateType.VersionTolerant)]
public partial class TestClass
{
[MemoryPackOrder(0)]
public int Id { get; set; }
[MemoryPackOrder(1)]
public string Name { get; set; } = default!;
}
で、もしこのクラスの仕様が変わって、FirstNameとLastNameにわけようってことになった場合、
[MemoryPackable(GenerateType.VersionTolerant)]
public partial class TestClass
{
[MemoryPackOrder(0)]
public int Id { get; set; }
[MemoryPackOrder(1)]
public string Name { get; set; } = default!;
}
[MemoryPackable(GenerateType.VersionTolerant)]
public partial class TestClassVer2
{
[MemoryPackOrder(0)]
public int Id { get; set; }
//[MemoryPackOrder(1)]
//public string Name { get; set; } = default!;
[MemoryPackOrder(2)]
public string FirstName { get; set; } = default!;
[MemoryPackOrder(3)]
public string LastName { get; set; } = default!;
}
という感じで、定義を変更した別バージョンのクラスを用意することで、TestClass
<-> TestClassVer2
で相互にシリアライズ/デシリアライズしてくれるようになります。
そのときのルールは下記の通り。
- 既存のフィールドのMemoryPackOrderのインデックスは変わらないこと
- 削除されたフィールドのMemoryPackOrderのインデックスを再利用しないこと
- 同じインデックスのフィールドの型は変更しないこと(名前は変更可)
シリアライザの仕様的に「フィールドの順番に値だけきちきち詰めていく」ということなので、MemoryPackOrder
で順番を固定してその順番の型を同じにしておけば、削除されたところや増えたところは適切に無視してくれるようになるわけです。
その代わりちょっとだけ処理に時間がかかるし、バイナリのサイズも大きくなるよということですが、元々が早いし一般的なサーバーとのやりとりであれば微々たるものでしょう。
まとめ
非常に実用的な機能が入りました。
運用中のシステムであってもデータの仕様が変わるのはよくある話なので、それにも対応しやすくなるのはいいことです。