トップ > Tech > CSharp > イベントをシリアライズしないようにする

イベントをシリアライズしないようにする

このページでは、クラスにシリアライズしたくないイベントが含まれている場合の、回避方法を示す。

イベントに NonSerialized は設定できない

クラスを BinaryFormatter などでシリアル化する場合、そのメンバはすべて [Serializable] でなければならない。シリアル化するクラスに [Serializable] でないメンバが含まれていると、コンパイル時ではなく、実行時に例外になるので、なんとも困ってしまう。

私の場合、INotifyPropertyChanged インターフェースを実装しているクラスで、PropertyChanged イベントを実装していた。PropertyChanged イベントは PropertyChangedEventHandler 型であるが、このクラスはシリアル化可能な型ではない。

シリアライズしようとすると下のように怒られてしまう。

アセンブリ 'WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' の型 'System.ComponentModel.PropertyChangedEventManager' はシリアル化可能として設定されていません。

通常イベントはシリアル化する必要がないと思うので、これを除外できればいいわけだ。 通常 [Serializable] なクラスのメンバーで除外したい変数に対しては次のように [NonSerialized] 属性をつければいい。

[NonSerialized]
public string Text;

だが、イベントの場合、これはうまくいかない。

[NonSerialized]
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

上のようにしても、

属性 'NonSerialized' は、この宣言型では無効です。'field' の宣言でのみ有効です。

と怒られてしまう。これは NonSerialized がフィールドにのみ有効な属性だから、である。

対策は field: をつける

これを回避するにはどうすればいいか調べてみると、ずばりのサイトが見つかった。

方法としては、下記のように [NonSerialized] の部分を [field: NonSerialized] 書き換えればいい。

[field: NonSerialized]
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

この field: のように指定については、下記を参照のこと。

これによって、PropertyChanged はシリアルライズ時は無視され、無事このクラスはシリアライズ可能となった。

(2010/09/29 16:14:07)
26925
プロフィール

Kenz Yamada(山田研二)。1984年生。大阪。ちょっとずつ好きなプログラム作ってます。 好きなものはカメラと旅行。ガジェットや身の回り、ちょっとこだわります。 詳しくは Web mixi で。

Bookmark and Share