い方は、直列化復元旧データタイプが変わったのか?
-
12-09-2019 - |
質問
していっているデータ格納用のバイナリーの直列化のための以下のクラス:
[Serializable]
public abstract class BaseBusinessObject
{
private NameValueCollection _fieldErrors = new NameValueCollection();
protected virtual NameValueCollection FieldErrors
{
get { return _fieldErrors; }
set { _fieldErrors = value; }
}
...
}
ある時点で、このクラスに変更したこ
[Serializable]
public abstract class BaseBusinessObject
{
private Dictionary<string, string> _fieldErrors = new Dictionary<string, string>();
protected virtual Dictionary<string, string> FieldErrors
{
get { return _fieldErrors; }
set { _fieldErrors = value; }
}
...
}
このことが問題deserializing旧データです。
私が最初に考えた上で実施 ISerializable
, が、このクラスには多くの特性ならびに数百にものを受け継ぎの授業を行うためにこのためです。
いどちらかの変更に古いデータに合わせて現在の構造中の直列化復元は、決して綺麗というレベルアップのデータです。
解決
追加の新たな_fieldErrors
異名という _fieldErrors2
, を行うと [Optional]
.その後の実施 [OnDeserialized]
法コピーからのデータ _fieldErrors
へ _fieldErrors2
(存在する場合)、クリア_fieldErrors.
他のヒント
データのみを内部的に使用されている場合は、私の最初の考えは、昔の「NameValueCollectionの」を使用して、あなたのバイナリデータをデシリアライズするためにいくつかの簡単なスローアウェイコードを書くDictionnaryにマッピングし、再シリアライズそれをすることです。それは、すべてのデータを処理するためには数日かかるだろうとしても、それはそれは古いデータをサポートするために、あなたの新しいコードにパッチを実装する価値はいないようです。
それは内部でのみ使用されていない場合であっても、輸入者が行くための最も簡単な方法のように思える。
OlivierDの良いアドバイスに加えて、私はあなたが両方のクラスを定義しますが、最初は、現在のバージョンとデシリアライズしようとお勧めしたいです。あなたのcatchブロックでは、現在の1にアップグレードして戻ってそれを保存し、レガシーバージョンとして、それをデシリアライズ。レガシーバージョンのインスタンスが存在しない場合、あなたはコードを削除することができます。
いくつかのオプションを調査した後、私は次のような結論を作っます:
理想的には私は、元のNameValueCollection
からの値にアクセスし、手動Dictionary<string, string>
に変換することができるであろう。これを行うための唯一の方法は、ISerializable
を実装することですが、これは二つの大きな問題を提起:レガシーデータの命名およびすべての継承クラス(その何百ものがある)の直列化ロジックを含めるまで一致します。
事実上、これは苦境に私を置きます。幸いなことに、私は、このフィールドは実際には、フォームの検証エラーの要約として使用され、最初の場所でシリアル化された取得すべきではないと判断することができたので、私は直列化からそれを除外しています。