オブジェクト保存

今回のレッスンでは、クラスオブジェクトの保存方法を学び、オブジェクトの保存と読み出しを実装します。

このコードは Memcached による基本型(int/bool)と自作クラスオブジェクトの保存を示しており、陥りやすい重要なポイントを紹介します。

自作エンティティクラスには [Serializable] 属性を付与する必要があります。付けないとシリアライズに失敗し、オブジェクト取得時にnullが返ります。

誤った実装

static void Main(string[] args)
{
    MemcachedClient mClient = new MemcachedClient();

    // 基本型の保存・取得(int、boolは標準対応、シリアライズ属性不要)
    mClient.Store(StoreMode.Set, "clicks", 1);
    var clicks = mClient.Get<int>("clicks");

    mClient.Store(StoreMode.Set, "isOk", true);
    var isOk = mClient.Get<bool>("isOk");

    // 自作オブジェクト保存
    var person = new Person { Id = 1, Name = "Jackson", AddTime = DateTime.Now };
    mClient.Store(StoreMode.Set, "person", person);
    var p = mClient.Get<Person>("person"); // ここでnullが返る
    Console.Read();
}

// 【NG】[Serializable] が不足
class Person
{
    public int Id { set; get; }
    public string Name { set; get; }
    public DateTime AddTime { set; get; }
}Code language: JavaScript (javascript)
発生する現象

var p = mClient.Get<Person>("person"); の実行結果が null になります。
原因:EnyimMemcached は既定で .NET のバイナリシリアライズを利用します。[Serializable]属性のないクラスはシリアライズできず、キャッシュから正常にデシリアライズできません。

正しい実装

エンティティクラスにシリアライズ属性を追加します。

[Serializable] // 必須の属性
public class Person
{
    public int Id { set; get; }
    public string Name { set; get; }
    public DateTime AddTime { set; get; }
}Code language: JavaScript (javascript)

追加後は Get<Person>("person") でオブジェクトを正しく取得できます。

補足情報

// ジェネリック取得:Get<T> 推奨、自動で型変換される
var p = mClient.Get<Person>("person"); 

// 非ジェネリックGet:objectが返るので手動でキャストが必要
var p2 = mClient.Get("person");Code language: JavaScript (javascript)
  • Get<T>(key):ジェネリックメソッド、優先して使用。取得失敗時は型の既定値を返す(参照型はnull)
  • Get(key):生のobjectを返す、自分で型キャストを行う必要あり

完全なサンプルコード

using Enyim.Caching;
using Enyim.Caching.Memcached;
using System;

[Serializable]
public class Person
{
    public int Id { set; get; }
    public string Name { set; get; }
    public DateTime AddTime { set; get; }
}

class Program
{
    static void Main(string[] args)
    {
        MemcachedClient mClient = new MemcachedClient();

        mClient.Store(StoreMode.Set, "clicks", 1);
        var clicks = mClient.Get<int>("clicks");

        mClient.Store(StoreMode.Set, "isOk", true);
        var isOk = mClient.Get<bool>("isOk");

        var person = new Person { Id = 1, Name = "Jackson", AddTime = DateTime.Now };
        mClient.Store(StoreMode.Set, "person", person);

        var p = mClient.Get<Person>("person");
        Console.WriteLine(p.Name); // Jackson が出力される

        Console.Read();
    }
}Code language: JavaScript (javascript)

オブジェクト保存

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です