WP7中的序列化 - 我缺少什么?

时间:2011-06-01 11:01:57

标签: serialization windows-phone-7

与墓碑相比,序列化对WP7应用来说非常重要。基于位置的应用程序风靡一时。但是当我试图将GeoCoordinate放入隔离的存储设置时,它后来无法再水化,我最终独立地序列化lat和lng,这非常不令人满意,因为我最终得到了大量的临时序列化代码。我用反射把它清理干净了,但实际上它真是一团糟。

这是什么交易?我还没有学到正确的方法吗?

如果没有,GeoCoordinate课程的作者在想什么?使用DataMember属性的注释就是它所要采用的所有注释。在WP7应用程序中,位置可能是app状态的一部分吗?

我已经在serialisation and isolated storage files以及this rather more interesting piece看到了这个链接到一个相当基本的DIY二进制序列化助手(微软的BinaryFormatter类不可用)。

芒果包括Silverlight4,或者我告诉我(我的笔记本没有足够的内存,而且必须遵守的她禁止我建立一个更大的系统,直到我们的八月滑雪之旅后) - 有谁知道这是否是否可以使用BinaryFormatter?我可以重现BinaryFormatter,但我宁愿没有。

2 个答案:

答案 0 :(得分:0)

除非我误解你,否则你能不能将GeoCoordinate的值转换为自定义的可序列化对象?重新水化只是反序列化您的对象并创建一个新的GeoCoordinate对象。

我不确定Mango工具包中是否可以使用BinaryFormatter,但Mango工具包已经用完(测试版),所以你可以take a look

答案 1 :(得分:0)

虽然我认为微软应该运用一些常识并确保像GeoCoordinate这样的类是DataContract可序列化的,但我找到了一个方便的解决方法。通常,当一个人正在进行此类工作时,一个人已经为BingRoute webservice或类似设备导入了界面。

显然,其中的所有类都是可序列化的,因此我将所有代码转换为使用BingRoute.Location类型而不是GeoCoordinate,问题就消失了。必要时,扩展方法ToGeoCoordinate()使得转换足够不引人注意,以至于现有代码的意图不明显。

public static GeoCoordinate ToGeoCoordinate(this BingRoute.Location loc)
{
  return new GeoCoordinate(loc.Latitude, loc.Longitude, loc.Altitude);
}

如果您接受我的建议,那么您迟早会错过GeoCoordinate的GetDistanceTo()方法。扩展方法也是你的朋友。

您可以将这两个点转换为GeoCoordinate并使用内置方法,但这会产生大量的瞬态对象,并且在某些时候,当垃圾收集器履行其职责时,您的应用程序会窒息。

我投入其他内置位置类型以获得良好的衡量标准。请注意,距离代码实现了Haversine,这是一个包含许多限制的Great Circle计算。注意事项。

public static double GetDistanceTo(this BingRoute.Location A, BingRoute.Location B)
{
  return GetDistanceTo(A.Latitude, A.Longitude, B.Latitude, B.Longitude);
}

public static double GetDistanceTo(
  this Microsoft.Phone.Controls.Maps.Platform.Location A, 
  Microsoft.Phone.Controls.Maps.Platform.Location B)
{
  return GetDistanceTo(A.Latitude, A.Longitude, B.Latitude, B.Longitude);
}

static double toRad = Math.PI / 180D;
static double toDeg = 180D / Math.PI;

static double GetDistanceTo(double lat1, double lng1, double lat2, double lng2)
{
  lat1 *= toRad;
  lng1 *= toRad;
  lat2 *= toRad;
  lng2 *= toRad;
  double sin_dLng_on2_squared = Math.Sin((lng2 - lng1) / 2);
  sin_dLng_on2_squared *= sin_dLng_on2_squared;
  double sin_dLat_on2_squared = Math.Sin((lat2 - lat1) / 2);
  sin_dLat_on2_squared *= sin_dLat_on2_squared;
  double a = sin_dLat_on2_squared + Math.Cos(lat1 * Math.Cos(lat2) * sin_dLng_on2_squared);
  double c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));
  return c * 6371000;
}

同样重要的是要注意,您存储的越多,您的应用启动速度就越慢,因为在激活时创建设置对象需要更长的时间。因此,您最好建议在此处仅存储简单的选项状态,并尽可能保留在隔离的存储文件中。