2016-08-17 18 views
1

私はBinaryFormatterでゲームのセーブをシリアライズしてデシリアライズしようとしています。 私はこのユーティリティメソッドを使用していますので、バージョン管理をサポートするためにISerializableインターフェイスを使用したり、各フィールドにAddValue()を手動で記述する必要はありません。BinaryFormaterを使用したシリアライズ - C#

public void Serialize(object obj, string path) 
{ 
    FieldInfo[] fieldsPublic = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance); 
    FieldInfo[] fieldsPrivate = obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance); 
    foreach (FieldInfo info in fieldsPublic) 
    { 
     object valiue = info.GetValue(obj); 
     if(!info.IsDefined(typeof(NonSerializedAttribute), true)) 
      fields.Add(info, info.GetValue(obj)); 
    } 
    foreach (FieldInfo info in fieldsPrivate) 
    { 
     if (info.IsDefined(typeof(SerializeField), true)) 
      fields.Add(info, info.GetValue(obj)); 
    } 
    BinaryFormatter bf = new BinaryFormatter(); 
    FileStream file = File.Create(path); 

    bf.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; 
    bf.Serialize(file, fields); 

    file.Close(); 
} 

このようにシリアル化すると、fieldsPublic内のフィールドにはパブリックメンバーしか含まれないという問題があります。また、[SerializeField]属性を持つプライベートメンバーを含める必要があります。しかし、この属性は、オブジェクトの最初のレベルでのみこの属性を持つフィールドをチェックするため、無視されます。

例、私はオブジェクトクラスをシリアル化:

class A 
{ 
    public B b; 
    [SerializeField] 
    private int value; // This is NOT ignored 
} 

class B 
{ 
    [SerializeField] 
    private int value; // This is ignored 
} 

どのように私はまた、[SerializeField]フィールド属性を持つプライベート変数をシリアル化することができますか?

ありがとうございました。

+1

"バージョン管理をサポートする"ようですが、将来バージョンの問題があると思われますか?バイナリシリアライゼーションは、トランスポート*メカニズム、異なるアプリケーション間(同じバージョンの)、異なるアプリケーションドメイン間、または同様のもの間で使用されることを意図しています。それは**記憶メカニズム*ではない**です。 –

+1

クラスに '[Serializable]'属性を付けるだけで、デフォルトの振る舞いに依存しないのはなぜですか?ところで、BinaryFormatterは最悪のシリアル化メソッドの1つですが、バージョニングの問題を避けたい場合は、他にも試してみることを強くお勧めします。 –

+0

BinaryFormatterはプライベートフィールドをシリアル化しません。プライベートメンバーをAからマッピングするためのあなたの努力は、Bのプライベートメンバーのマッピングにも拡張されません。あなたがやろうとしているのは、ディープコピーでよく経験される問題の傾向があることです。あなたはそれを難し​​い方法でやっています。 – Biscuits

答えて

0

私はこれを解決しました。

シリアライザが正しく動作しています。私の考えていたバージョニングは、フィールドの追加や削除についてのものでしたので、クラッシュしませんでした。古いセーブでゲームを読み込んでいます。 しかしこれもシリアライザで処理されます。

関連する問題