ToLookup IEqualityComparer参数始终为null

时间:2015-03-10 14:45:59

标签: c# lookup

我偶然发现了一个奇怪的问题,这对我来说并没有多大意义。

我有一个带有属性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只是没有将对象传递给给定的比较器实例吗?!

1 个答案:

答案 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?