与墓碑相比,序列化对WP7应用来说非常重要。基于位置的应用程序风靡一时。但是当我试图将GeoCoordinate放入隔离的存储设置时,它后来无法再水化,我最终独立地序列化lat和lng,这非常不令人满意,因为我最终得到了大量的临时序列化代码。我用反射把它清理干净了,但实际上它真是一团糟。
这是什么交易?我还没有学到正确的方法吗?
如果没有,GeoCoordinate课程的作者在想什么?使用DataMember属性的注释就是它所要采用的所有注释。在WP7应用程序中,位置可能是app状态的一部分吗?
我已经在serialisation and isolated storage files以及this rather more interesting piece看到了这个链接到一个相当基本的DIY二进制序列化助手(微软的BinaryFormatter类不可用)。
芒果包括Silverlight4,或者我告诉我(我的笔记本没有足够的内存,而且必须遵守的她禁止我建立一个更大的系统,直到我们的八月滑雪之旅后) - 有谁知道这是否是否可以使用BinaryFormatter?我可以重现BinaryFormatter,但我宁愿没有。答案 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;
}
同样重要的是要注意,您存储的越多,您的应用启动速度就越慢,因为在激活时创建设置对象需要更长的时间。因此,您最好建议在此处仅存储简单的选项状态,并尽可能保留在隔离的存储文件中。