c# - Implementing a geographic coordinate class: equality comparison -
i 'm integrating geographic coordinate class codeplex personal "toolbox" library. class uses float fields store latitude , longitude.
since class geocoordinate implements iequatable<geocoordinate>, habitually wrote equals method so:
public bool equals(geocoordinate other) { if (other == null) { return false; } return this.latitude == other.latitude && this.longitude == other.longitude; } at point stopped , considered 'm comparing floating point variables equality, no-no. thought process went follows:
i can imagine setting
latitude,longitudeproperties once, means there no errors being accumulated mess comparisons.on other hand, it's possible (albeit pointless) write
var geo1 = new geocoordinate(1.2, 1.2); var geo2 = new geocoordinate(1.2, 1.2); // geo1.equals(geo2) true, but: geo2.latitude *= 10; geo2.latitude /= 10; // think bets offof course not can imagine doing, if public interface of class allows
equalsshould able handle it.comparing equality using
difference < epsilontest solve problem of comparing 2 instances, create more problems:- how make equality transitive? sounds impossible.
how produce same hash code all values compare equal?
let's
epsilon = 0.11(random example). followsgeocoordinate { 1, 1 }need same hash codegeocoordinate { 1.1, 1.1 }. latter need same hash codegeocoordinate { 1.2, 1.2 }. can see going: all instances need have same hash code.
a solution of make
geocoordinateimmutable class. solvegethashcodeproblem: based on latitude , longitude (what else), , if these are mutable usinggeocoordinatekey dictionary asking trouble. however, make class immutable has own drawbacks:- you cannot instantiate-and-configure instances of class (the wpf paradigm), might pain in cases
- serialization become pain due loss of parameterless constructor (i 'm not .net serialization expert that's detail see here)
which approach suggest? it's easy make class fit requirements have right (just make immutable), there better way?
edit: added item 3 in list above, shifting previous item 3 position 4.
solution
i 'm going allow more time feedback, presently 'm going immutable approach. struct (because that's now) relevant members can seen here; comments , suggestions more welcome.
a "location" longitude/latitude me falls quite nicely "immutable value" slot. position itself doesn't change - if change latitude different position. there, could struct; float struct same size x64 reference anyway, no real down side.
re equality; if position isn't quite same, isn't "equals", @ least in "key" perspective, i'd happy == here. add "is within (x) distance" method if helped. of course, great-arc geometry isn't totally free either ;p
thoughts though:
- it should override
bool equals(object)addingbool equals(geocoordinate) - it should override
gethashcode(), implementiequatable<geocoordinate> - static operators nice-to-have optional extra
Comments
Post a Comment