我偶然发现了一个奇怪的问题,这对我来说并没有多大意义。
我有一个带有属性Location的业务对象Address(类型为SqlGeography)。为了我的要求,我必须对位置进行查找,因为每个确切位置可能有多个地址。
由于SqlGeography是一个复杂的类型,我怀疑可能查找不起作用,因为它不是基于位置坐标由于某种原因所以我这样做:
public class Address
{
public Address(byte[] location)
{
Location = SqlGeography.Deserialize(new SqlBytes(location));
}
public SqlGeography Location { get; set; }
}
public class SqlGeographyComparer : IEqualityComparer<SqlGeography>
{
public bool Equals(SqlGeography x, SqlGeography y)
{
// !!! always entered but for some reason x + y always null
if (x == null && y == null)
return true;
if (x == null ^ y == null)
return false;
return x.STEquals(y).IsTrue;
}
public int GetHashCode(SqlGeography obj)
{
return obj.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
var addresses = GetAddresses();
// should be 2 but it's 3 results
var addressesLookup = addresses.ToLookup(d => d.Location);
// should be 2 but it's 3 results
var addressesLookup2 = addresses.ToLookup(d => d.Location, new SqlGeographyComparer());
Console.ReadLine();
}
private static IList<Address> GetAddresses()
{
// 230,16,0,0,1,12,213,97,212,23,126,78,72,64,109,51,198,37,82,163,32,64
var result = new List<Address>();
result.Add(new Address(new byte[] { 230, 16, 0, 0, 1, 12, 213, 97, 212, 23, 126, 78, 72, 64, 109, 51, 198, 37, 82, 163, 32, 64 }));
result.Add(new Address(new byte[] { 230, 16, 0, 0, 1, 12, 213, 97, 212, 23, 126, 78, 72, 64, 109, 51, 198, 37, 82, 163, 32, 64 }));
result.Add(new Address(new byte[] { 230, 16, 0, 0, 1, 12, 213, 97, 212, 23, 126, 78, 72, 64, 109, 51, 198, 37, 82, 163, 32, 63 }));
return result;
}
}
这是一个奇怪的错误,我还没有听说ToLookup只是没有将对象传递给给定的比较器实例吗?!
答案 0 :(得分:0)
一旦我更改了SqlGeographyComparer以覆盖其方法,如下所示:
public int GetHashCode(SqlGeography obj)
{
unchecked
{
return ((obj.Lat.GetHashCode() * 397) ^ obj.Long.GetHashCode());
}
}
它工作正常。
结果是GetHashCode必须模仿所需的相等比较(如Equals所示),以使参数正常工作。
实施GetHashCode的参考,以防其他人偶然发现这个问题并且想知道397:
What is the best algorithm for an overridden System.Object.GetHashCode?