2011-07-01 10 views
3

に関与しているとき、私は、オブジェクトのインスタンスのリストを保持しているManagerと呼ばれるシングルトンクラスがあります。シリアライズとデシリアライズの参照をC#

static class Manager 
{ 
    static List<Foo> Foos = new List<Foo>(); 
} 

を、私は、その後の参照を使用するクラスと呼ばれるメーターを使用して、オブジェクトインスタンスのコレクションを持っています

class Meter 
{ 
    public Foo MyFoo = null; 
} 

... 

public void CreateMeter(int UserChoice) 
{ 
    Meter MyMeter = new Meter(); 
    MyMeter.MyFoo = Manager.Foos[UserChoice]; 
} 

アプリケーションがメーターのすべてのインスタンスと一緒にFOOSにはFooのインスタンスをシリアライズするプロジェクトファイルを保存します。リスト内の項目FOOSへ。

私の問題は、この配置を逆シリアル化する方法です。現在、私は次の操作を行います。

  • がMYFOOプロパティにはFooのインスタンスを含んメートルのインスタンスをデシリアライズ
  • Manager.Foosを再構築するためにはFooのプロジェクト全体のインスタンスをデシリアライズ
  • 検索Manager.FoosとMyMeter.MyFooの一致する参照を見つけて、Manager.Foosからの参照を割り当てます。

これは私には見苦しくて、伸ばしすぎないようです。むしろMeterファクトリは、将来のMeterがManagerだけでなく他の場所からFooインスタンスを参照する可能性があるため、デシリアライゼーション中にManager.Foosを検索する必要はありません。

オブジェクトへの参照を容易に再構築できる、この逆シリアル化の問題に対する単純で柔軟な代替ソリューションはありますか?

+0

なぜ 'MyMeter.MyFoo'プロパティで参照される' Foo'インスタンスを 'MyMeter'インスタンスとともに直列化/逆シリアル化できないのですか? –

+0

です。しかし、Fooの同じインスタンスが複数のメーターで使用される可能性があり、デシリアライズ後に同じものであることを知る必要があります。 – Andy

+0

私はXElementなどで自分のシリアル化/逆シリアル化メソッドを使用していることを指摘しておきます。 – Andy

答えて

0

おかげでマルクや提案のために皆を。 Marcの重要なアイデアとHenkのオブジェクトIDジェネレータに基づいて、これまでのところ私はこれを持っています。

Fooは、一意のGuidを含むGuidプロパティを定義します。これはコンストラクタで生成されますが、シリアライズ/デシリアライズで保存/復元することもできます。

class Foo 
{ 
    public Guid TheGuid = Guid.NewGuid(); 
} 

メーターはもはや代わりに、それはGUIDを使用して、参照を使用:

class Meter 
{ 
    public Guid FooGuid; 
} 

メートルが作成されるGUIDが接続を確立:

public void CreateMeter(int UserChoice) 
{ 
    Meter MyMeter = new Meter(); 
    MyMeter.FooGuid = Manager.Foos[UserChoice].TheGuid; 
} 

メータがシリアルである場合/デシリアライズされたGUIDが格納されます/ロードされます。

1つの欠点は、メーターに関連付けられたFooインスタンスにアクセスする必要がある場合です。代わりに、直接、パフォーマンスヒットが発生します検索が実行されなければならないの参照を使用する:

class Manager 
{ 
    public List<Foo> Foos = new List<Foo>(); 

    public Foo GetFooFromGuid(Guid SearchGuid) 
    { 
     // search Foos and return instance with Guid == SearchGuid 
    } 
} 

このアプローチの利点は、今、私は、デリゲートを作成して、メーターに関連付けるはFooの複数のソースを持つことができるということです。

Func<Guid, Foo> FooSource; 

FooSource ManagerFooSource = Manager.GetFooFromGuid; 
4

シリアル化は難しいです:)形式と混乱が痛みでない方法でこれを自動的に行う

。共通のトリックは、中央のマップを使用して、デ/シリアライズ中に関連のない不透明なキーを割り当てることです。 DataContractSerializerでこれを見るには、コンストラクタで参照追跡を有効にします。このキーを使用して、既存のオブジェクトが代替オブジェクトであるかどうかをチェックします。

個人的には、複雑なIMOを取得したら、事前に準備した航空機を使用することになります。専用のライブラリの中でさえ、少し難しいです。私が使用しているアプローチ(protobuf-net)はかなりよく似ていますが、読みにくいです(バイナリ高密度出力など)。マネージャークラスの

0

それぞれのFoo CLをFooの中

public ulong MyId

を追加CTOR

MyId=Manager.IdProvider++;

を追加するのFooクラスに

public static ulong IdProvider=0

を追加assには一意のID(最大2^64-1インスタンス)があり、再構築時に一意のIDを追加できるようにIdProviderを保存するだけです。

Fooの一意のIDを保持するMeterクラスを変更し、Managerクラスの「Foos」にリンクするプロパティ(get; set)を提供することを検討してください。

私は完全にあなたが望むものを理解していないが、このような観点から、あなたはかなりの混乱を作った:P

+0

これは、アプリケーションのユーザーによって作成されたオブジェクトの2つのリストで、1つのリストは、プロジェクトファイルに保存する必要がある他のリストを参照します。私はそれが非常に一般的な状況だと思っただろう混乱ではなく、むしろ。 – Andy

関連する問題