このページでは、クラスにシリアライズしたくないイベントが含まれている場合の、回避方法を示す。
クラスを 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 がフィールドにのみ有効な属性だから、である。
これを回避するにはどうすればいいか調べてみると、ずばりのサイトが見つかった。
方法としては、下記のように [NonSerialized] の部分を [field: NonSerialized] 書き換えればいい。
[field: NonSerialized]
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
この field: のように指定については、下記を参照のこと。
これによって、PropertyChanged はシリアルライズ時は無視され、無事このクラスはシリアライズ可能となった。
Kenz Yamada(山田研二)。1984年生。大阪。ちょっとずつ好きなプログラム作ってます。
好きなものはカメラと旅行。ガジェットや身の回り、ちょっとこだわります。
詳しくは Web mixi で。