atsukanrockのブログ

Microsoft系技術を中心にぼちぼち更新します

.NET Frameworkで、シリアル化可能なタイプセーフenumを実装する - その3(今度こそ完成?)

はじめに

昨日のエントリに対して、またもやid:zeclさんに言及いただいた。以下にその言及内容を引用する。

そうですよね。IObjectReferenceインターフェイスを利用すれば、静的クラスのシングルトンが表現できますものね。

ちなみに、IObjectReferenceインターフェイスを実装する静的クラスのシングルトンヘルパーとして作用するクラスに、

ISerializableインターフェイスを実装する必要はないと思います。SerializableAttributeさえ付加しておけばよいのではないでしょうか。

えっ、そうなの!?ということで、昨日のエントリのサンプルを、変更してみる。

アドバイスをいただいたzeclさんに、重ね重ね感謝します。

サンプル

変更するのはTypeSafeEnum<T>.ObjectReference<U>クラスだけなので、その部分のみの変更後のサンプルを、以下に示す。

    [Serializable]
    private sealed class ObjectReference<U> : IObjectReference
        where U : TypeSafeEnum<U>
    {
        private readonly int _serial;

        Object IObjectReference.GetRealObject(StreamingContext context)
        {
            return TypeSafeEnum<U>.__instances[_serial];
        }
    }

これで、動作する。恥ずかしながら、実際に動かしてみるまで意味がわからなかった。

ObjectReference<U>側のフィールド名が_serialで、TypeSafeEnum<T>の_serialとフィールド名が一致していることが重要だ。そうすることで、ObjectReference<U>の_serialフィールドに、TypeSafeEnum<T>のシリアル化の過程でSerializationInfoに保存しておいた_serialフィールド値が、SerializableAttribute属性によって、自動的に*1設定される。IObjectReferenceってそう動くのね…。

*1:フレームワーク側がやってくれる、という意味で