2011-07-01 46 views
3

我有一个单独的类名为经理持有对象实例的列表,涉及:序列化和反序列化时参考用C#

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

然后我有使用采用参考一类叫做仪表对象实例的集合列表中的项目FOOS:

class Meter 
{ 
    public Foo MyFoo = null; 
} 

... 

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

当应用程序保存它系列化美孚在FOOS的情况下,与仪表的所有实例沿着一个项目文件。

我的问题是如何反序列化这种安排。目前,我做到以下几点:

  • 反序列化的Foo的项目范围内的情况下重建Manager.Foos
  • 反序列化的仪表实例,其中包括富的实例为MyFoo财产
  • 搜索Manager.Foos和找到MyMeter.MyFoo的匹配参考,然后从Manager.Foos中分配参考。

这在我看来,笨重,不太容易扩展。我宁愿Meter工厂在反序列化过程中不需要搜索Manager.Foos,因为将来Meter可能会将其作为来自其他地方的Foo实例,而不仅仅是Manager。

有一个简单而灵活的替代解决这个问题,反序列化到哪里对象的引用可以容易恢复?

+0

为什么MyMeter.MyFoo属性引用的'Foo'实例不能与MyMeter实例一起序列化/反序列化? –

+0

是。但是Foo的相同实例可能会被多个计量表使用,我必须知道这是反序列化后的同一个实例。 – Andy

+0

我应该指出,我正在使用自己的序列化/反序列化方法与XElement等 – Andy

回答

0

感谢Marc和其他人的建议。基于Marc的核心思想和亨克的对象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被存储/加载。

一个缺点是需要访问与仪表关联的Foo实例。而不是直接使用查找已被执行的参考,这将导致性能命中:

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

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

这种方法的好处是,现在我可以创建一个委托,并有富的多源与米关联:

Func<Guid, Foo> FooSource; 

FooSource ManagerFooSource = Manager.GetFooFromGuid; 
4

序列化是很难:)

这样做可以在不乱用格式是一种痛苦的方式自动完成。这里常见的技巧是使用中央映射在de/serialising时分配不相关的不透明密钥。您可以通过在构造函数中启用引用跟踪来在DataContractSerializer中看到此内容。这个键然后用来检查现有的对象作为替代。

个人而言,当它得到的是复杂的IMO是时候使用预罐装aerializer;即使在专用库中,也有一定的挑战性。我使用的方法(protobuf-net)非常相似,但难于阅读(二进制密集输出等)。

0

Manager类添加

public static ulong IdProvider=0

在Foo类添加

public ulong MyId

在富

构造函数添加

MyId=Manager.IdProvider++;

每个富CL屁股将有一个唯一的ID(最多2^64-1实例),只需保存IdProvider,以便在重建时可以继续添加唯一的ID。

你可能要考虑改变仪表类来保存富的唯一ID,并提供一个属性(获取;集)在Manager类链接到“FOOS”。

我还没有完全了解你想要什么,但是从这个角度来看,你已经取得了相当混乱:对

+0

这是应用程序用户创建的两个对象列表,一个列表引用另一个列表,两个列表都需要保存在项目文件中。我认为这不是一团糟,而是一种非常普遍的情况。 – Andy