На данный момент я придумал эти две реализации, основанные на простом интерфейсе:
Интерфейс
Код: Выделить всё
public interface ILatLng
{
double Lat { get; }
double Lng { get; }
}
Код: Выделить всё
public class CLatLng : ILatLng
{
public double Lat { get; private set; }
public double Lng { get; private set; }
public CLatLng(double lat, double lng)
{
this.Lat = lat;
this.Lng = lng;
}
public override string ToString()
{
return String.Format("{0},{1}", this.Lat, this.Lng);
}
public override bool Equals(Object obj)
{
if (obj == null)
return false;
CLatLng latlng = obj as CLatLng;
if ((Object)latlng == null)
return false;
return (this.Lat == latlng.Lat) && (this.Lng == latlng.Lng);
}
public bool Equals(CLatLng latlng)
{
if ((object)latlng == null)
return false;
return (this.Lat == latlng.Lat) && (this.Lng == latlng.Lng);
}
public override int GetHashCode()
{
return (int)Math.Sqrt(Math.Pow(this.Lat, 2) * Math.Pow(this.Lng, 2));
}
}
Код: Выделить всё
public struct SLatLng : ILatLng
{
private double _lat;
private double _lng;
public double Lat
{
get { return _lat; }
set { _lat = value; }
}
public double Lng
{
get { return _lng; }
set { _lng = value; }
}
public SLatLng(double lat, double lng)
{
this._lat = lat;
this._lng = lng;
}
public override string ToString()
{
return String.Format("{0},{1}", this.Lat, this.Lng);
}
}
- Структура всегда имеет структуру без параметров. конструктор, что означает, что вы не можете принудительно создать его экземпляр с помощью конструктора, который ожидает два свойства (для lat и lng), как это можно сделать с классом.
- Структура (будучи типом значения) никогда не может быть нулевой, поэтому всегда будет содержать значение. Но вы все равно можете делать подобные вещи, реализуя интерфейс:
Код: Выделить всё
ILatLng s = new SLatLng(); s = null;
- Если я использую структуру, нужно ли мне переопределить Equals, GetHashCode() и т. д.? Мои тесты показывают, что сравнения работают корректно и без этого (в отличие от классов). Так нужно ли это?
- Я чувствую себя более «комфортно», используя классы, так лучше ли просто придерживаться их, поскольку я лучше знаю, как они себя ведут? Будут ли люди, использующие мой код, сбиты с толку семантикой типов значений, особенно при работе с интерфейсом?
- В реализации CLatLng , кажется ли переопределение GetHashCode() приемлемым? Я «украл» это из этой статьи, поэтому не уверен!
Подробнее здесь: https://stackoverflow.com/questions/615 ... coordinate