2011-08-01 19 views
1

バイナリシリアル化を使用してデータを保存します。今度はプログラム内のフィールドをInt32からstructに変更しました。しかし、私はまだ後方互換性があるようにフィールドをInt32として保存する必要があります。それ、どうやったら出来るの?構造体をカスタマイズして、Int32としてシリアル化する

背景情報 私のプログラムはDelphiから移植され、多くの配列を使用します。問題は、デルファイのリストが1から数え始めていることです。ビルコルートは、私が現在C#で開発しているときにインデックスを追跡するのを難しくしました。したがって、構造体を使用して、1ベースのインデックスを扱いやすくします。私がプログラム全体を修正するまで、0ベースの配列。構造体との1とint32の持つ1 -

コード

public void Save() 
    { 
      using (var writer = File.Open(Path, FileMode.Create)) 
      { 
       var serializer = new BinaryFormatter(); 
       serializer.Serialize(writer, _data); 
      } 
    } 

    private void Load() 
    { 
     using (var reader = File.Open(Path, FileMode.Open)) 
     { 
       var deserializer = new BinaryFormatter(); 
       _data = (Foo) deserializer.Deserialize(reader); 
     } 
    } 

public struct Indexer 
{ 
    //0-baserat index 
    private int _index; 

    public Indexer(int index) 
    { 
     _index = index; 
    } 

    static public implicit operator Indexer(int index) 
    { 
     return new Indexer(index); 
    } 

    static public implicit operator int(Indexer indexer) 
    { 
     return indexer._index; 
    } 

    public override string ToString() 
    { 
     return (_index + 1).ToString(); 
    } 

    ... 
    } 
+3

'struct'の定義は何ですか? –

+0

「バイナリシリアル化」とは、「BinaryFormatter」を意味しますか? –

+0

@ George Duckett - コードを追加しました。 – magol

答えて

0

従来型のInt32型のフィールドを追加したり、構造体フィールドを追加することができます。 [OnDeserialized]属性(および適切な引数)を使用してメソッドを作成し、intフィールドからstructフィールドを初期化します。たとえば、intフィールドがゼロでなく、構造体がデシリアライズ後にデフォルト値を持ち、データが古い形式から。

private int intValue;    // Legacy field 
private SomeStruct structValue;  // New field 

[OnDeserialized] 
private void OnDeserialized(StreamingContext context) 
{ 
    if (intValue != 0) 
    { 
     // Old format, initialize struct with int value. 
     structValue = new SomeStruct(intValue); 
    } 
} 

これは完全にエレガントではありませんが、他の方法もありますが、2つのフィールドを保持しても構わない場合は、これは簡単な方法の1つです。上記のコードでは、ゼロが古いintフィールドの "missing"値を示していることを前提としています。

0

は、私が唯一の方法は、2つのクラスを持つことになりますね。 その後、シリアル化した後、一方を他方に変換することができます。下位互換性はないことが明示されています。

0
int n = YourStruct.SomeIntVar; 
Marshal.WriteInt32(hBuffer, n); 

データがアーカイブにシリアル化される方法によって決まりますが、これがあなたのケースで機能するかどうかはわかりません。メモリまたは共有メモリ(hBuffer)上のデータを直接操作する場合は、上記のスニペットが役立ちます。

0

ISerializerSurrogate

これは、あなたがシリアライズ/デシリアライズプロセスを制御できるようになります。

関連する問題