实施地理坐标类:相等性比较 [英] Implementing a geographic coordinate class: equality comparison

查看:94
本文介绍了实施地理坐标类:相等性比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将CodePlex的地理坐标类集成到我的个人工具箱库中。此类使用 float 字段存储纬度和经度。

I 'm integrating a geographic coordinate class from CodePlex to my personal "toolbox" library. This class uses float fields to store latitude and longitude.

由于该类 GeoCoordinate 实现了 IEquatable< GeoCoordinate> ,我习惯性地编写了 Equals 方法,如下所示:

Since the class GeoCoordinate implements IEquatable<GeoCoordinate>, I habitually wrote the Equals method like so:

public bool Equals(GeoCoordinate other)
{
    if (other == null) {
        return false;
    }

    return this.latitude == other.latitude && this.longitude == other.longitude;
}

这时我停下来,认为我正在比较浮点变量平等,这通常是禁忌。然后我的思考过程大致如下:

At this point I stopped and considered that I 'm comparing floating point variables for equality, which is generally a no-no. My thought process then went roughly as follows:


  1. 我只能想象设置 Latitude Longitude 属性一次,这意味着不会积累任何错误来弄乱我的比较。

  1. I can only imagine setting the Latitude and Longitude properties once, which means that there will be no errors being accumulated to mess up my comparisons.

另一方面,有可能(尽管毫无意义)写

On the other hand, it's possible (albeit pointless) to write

var geo1 = new GeoCoordinate(1.2, 1.2);
var geo2 = new GeoCoordinate(1.2, 1.2);

// geo1.Equals(geo2) will definitely be true, BUT:

geo2.Latitude *= 10;
geo2.Latitude /= 10;

// I would think that now all bets are off

当然这不是我能想象的事情,但是如果类的公共接口允许它,那么 Equals 应该可以处理它。

Of course this is not something I can imagine doing, but if the public interface of the class allows it then Equals should be able to handle it.

使用差异<进行相等性比较。 epsilon 测试将解决比较两个实例的问题,但会产生更多问题:

Comparing for equality using a difference < epsilon test would solve the problem of comparing two instances, but create more problems:


  • 如何使等式可传递?

  • 如何为所有比较相等的所有值生成相同哈希码?

让我们说 epsilon = 0.11 (随机示例)。因此, GeoCoordinate {1,1} 将需要与 GeoCoordinate {1.1,1.1} 相同的哈希码。但是后者将需要与 GeoCoordinate {1.2,1.2} 相同的哈希码。您可以看到它的去向:所有实例都需要具有相同的哈希码

Let's say that epsilon = 0.11 (random example). It follows that GeoCoordinate { 1, 1 } would need the same hash code as GeoCoordinate { 1.1, 1.1 }. But the latter would need the same hash code as GeoCoordinate { 1.2, 1.2 }. You can see where this is going: all instances would need to have the same hash code.

所有这些的解决方案是使 GeoCoordinate 成为不可变的类。这也可以解决 GetHashCode 问题:它基于纬度和经度(还有哪些),并且如果它们是可变的,则使用 GeoCoordinate 作为字典的键正在麻烦。但是,使类不可变有其自身的缺点:

A solution to all of this would be to make GeoCoordinate an immutable class. This would also solve the GetHashCode problem: it is based on latitude and longitude (what else), and if these are are mutable then using GeoCoordinate as a key into a dictionary is asking for trouble. However, to make the class immutable has its own drawbacks:


  • 您不能实例化和配置该类的实例(WPF范例) ,在某些情况下可能会很痛苦

  • 由于缺少无参数构造函数,串行化也可能会很痛苦(我不是.NET序列化专家,所以足够详细了正如我在这里看到的那样)

您会建议哪种方法?使班级适合我现在的要求很容易(只是使其不可变),但是还有更好的方法吗?

Which approach would you suggest? It's easy to make the class fit the requirements I have right now (just make it immutable), but is there some better way?

编辑 :我在上面的列表中添加了项目3,将上一个项目3移到了位置4。

Edit: I added an item 3 in the list above, shifting the previous item 3 to position 4.

我将花更多时间进行反馈,但是目前,我将采用不变的方法。可以看到具有相关成员的 struct (因为现在是这样)这里;

I 'm going to allow some more time for feedback, but presently I 'm going with the immutable approach. The struct (because that's what it is now) with the relevant members can be seen here; comments and suggestions more than welcome.

推荐答案

对我来说,具有经度/纬度的位置很好地属于不变值 广告位。 位置本身不会改变-如果您更改的是不同位置的纬度。从那里,它可以成为结构;对于 float 而言,结构的大小与x64引用的大小相同,因此没有任何缺点。

A "location" with longitude/latitude to me falls quite nicely into the "immutable value" slot. The position itself doesn't change - if you change the latitude that is a different position. From there, it could be a struct; for float the struct would be the same size as an x64 reference anyway, so no real down side.

再平等;如果位置不完全相同,则至少在关键角度而言,它不是等于,因此我对 == 感到满意。如果有帮助,您可以添加在(x)距离之内的方法。当然,大弧几何也不是完全完全免费; p

Re equality; if the position isn't quite the same, it isn't "equals", at least in the "key" perspective, so I'd be happy with == here. You could add a "is within (x) distance" method if it helped. Of course, great-arc geometry isn't exactly totally free either ;p

但是要考虑:


  • 它应该覆盖 bool Equals(object)以及添加 bool Equals(GeoCoordinate)

  • 它应覆盖 GetHashCode()并实现 IEquatable< GeoCoordinate>

  • 静态运算符是一个不错的可选额外选项

  • it should override bool Equals(object) as well as adding a bool Equals(GeoCoordinate)
  • it should override GetHashCode() and implement IEquatable<GeoCoordinate>
  • static operators are a nice-to-have optional extra

这篇关于实施地理坐标类:相等性比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆