1

TL;博士; 是否有一个库或协议允许我从 .NET 应用程序序列化一些数据并在 WP、Win8、iOS 和 Android 上反序列化,同时保留对象之间的引用,就像它们在代码中一样,即如果单个实例 X 是 Y 的成员并且Z 当 Y 和 Z 被反序列化时,应该只有一个 X 对象。

详细版本:

我希望能够序列化 A 和 B 类型的一些对象,其中 A 具有 B 类型的成员,而 B 的一个实例可以是 A 的许多实例的成员。我应该能够在 WP、Win8、iOS 和反序列化数据时应保持与Android相同的关系。遗憾的是,我现在无法在 Android 和 iOS 上进行测试。

序列化机制的要求

  • 反序列化时保留对象引用
  • 序列化的开销并不重要,因为设备将获得新数据,例如每三个月一次
  • 虽然开销并不重要,但重要的是对同一对象的引用不要序列化一次,因为这可能会导致非常大的序列化数据。
  • 能够使用 .NET 进行序列化。不需要在其他平台上进行序列化。
  • 能够在 WP、Win8、iOS、Android 上反序列化


[DataContract(IsReference = true)]
public class A
{
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public B MemberB { get; set; }
}

[DataContract(IsReference = true)] public class B { [DataMember] public string Name { get; set; } }

示例对象图:


var b1 = new B { Name = "B1" };
var aa = new List { new A { MemberB = b1, Name = "A1" }, new A { MemberB = b1, Name = "A2" } };

我尝试使用 DataContract 序列化并将 IsReference = true 添加到 DataContract 属性。这就像桌面 .NET 和 WP 之间的一种魅力,我认为它可以在 Windows 8 上运行,但我什至找不到在 iOS 和 Android 上反序列化 DataContractSerialization 的方法,而无需编写自己的反序列化器,更不用说开箱即用的支持保留引用了. 如果有一个库可以在 iOS 和 Android 上提供反序列化而无需额外的努力,那么 DataContract 序列化对我来说将是完美的。

我还尝试了 OData 服务。OData 具有适用于 iOS 和 Android 的客户端库,但它是否按预期工作。似乎实体引用上是否有 PK 将被保留。我在 WP 和 .NET 控制台应用程序上进行了测试,如下所示:

DemoService service = new DemoService(new Uri("http://services.odata.org/OData/OData.svc/"));
var productsQuery = (DataServiceQuery<Product>)
                    (from p in service.Products.Expand("Category")
                     where p.Category.ID == 1
                     select p);

productsQuery.BeginExecute(
    (result) =>
        {
            var actualProducts = productsQuery.EndExecute(result).ToList();
            System.Diagnostics.Debug.WriteLine(actualProducts[2].Category == actualProducts[4].Category); //outputs true because both categories are the same
        },
    null);

它似乎有效,但我是否正确地进行了测试,它是否适用于 iOS 和 Android 客户端?我想避免使用 OData,因为它对我的情况来说似乎太重了。

我意识到我可以给每个对象一个 ID,并且只使用 ID 来建模对象图,但我希望有一个更清洁的解决方案。我还想避免编写自己的序列化代码。

子问题:

  1. 有没有办法在 iOS 和 Android 上反序列化 DataContract 序列化而不编写我自己的反序列化器
  2. iOS 和 Android 的 OData 客户端是否保留对象引用?他们容易相处吗
  3. iOS 版 Mono 和 Android 版 Mono 是否支持 DataContract 反序列化,同时保留对象引用?

谢谢你的时间。

4

1 回答 1

3

我会使用谷歌的协议缓冲区。其他语言还有其他实现,包括 Objective C 和 C#。

更新:

如果我这样做,我会开始在所有地方使用 .NET,包括在 Android 上(通过使用 MonoDroid)和(在 iOS 上使用 MonoTouch)。是的,您现在可以在任何平台上共享 C# 代码!

我希望序列化的每个对象都有一个定义为 Protocol-Buffer 对象的等效对象。每个对象都有一个序列化的哈希值作为它的 ID。对象中的每个引用都将被定义为一个哈希值。

然后,您在每个对象中都有一些代码来遍历它下面的对象,并在您进行时序列化到协议缓冲区对象。填充哈希值引用。

如果不存在,每个对象引用都会被查找并存储在对象的字典(哈希值/地址)中。这也是序列化的。这会阻止您对对象进行两次序列化,因为该对象在整个操作中仅被序列化/反序列化一次。这是通过设置/清除字典中对象的地址来完成的。

在这没什么大不了之前,我已经写了这些东西。

于 2012-09-04T14:44:39.533 回答