私は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]フィールド属性を持つプライベート変数をシリアル化することができますか?
ありがとうございました。
"バージョン管理をサポートする"ようですが、将来バージョンの問題があると思われますか?バイナリシリアライゼーションは、トランスポート*メカニズム、異なるアプリケーション間(同じバージョンの)、異なるアプリケーションドメイン間、または同様のもの間で使用されることを意図しています。それは**記憶メカニズム*ではない**です。 –
クラスに '[Serializable]'属性を付けるだけで、デフォルトの振る舞いに依存しないのはなぜですか?ところで、BinaryFormatterは最悪のシリアル化メソッドの1つですが、バージョニングの問題を避けたい場合は、他にも試してみることを強くお勧めします。 –
BinaryFormatterはプライベートフィールドをシリアル化しません。プライベートメンバーをAからマッピングするためのあなたの努力は、Bのプライベートメンバーのマッピングにも拡張されません。あなたがやろうとしているのは、ディープコピーでよく経験される問題の傾向があることです。あなたはそれを難しい方法でやっています。 – Biscuits