Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is this generating hash of 0?

I am trying to use some code that will generate hashcode based on the value of all properties inside an object, but the following returns a 0 for the HashCodeOnProperties

Console.WriteLine("Hello, World!");

var request = new Request()
{

    NorthEastLatitude = 43.13306116240615,
    NorthEastLongitude = -80.9355926513672,
    NorthWestLatitude = 43.13306116240615,
    NorthWestLongitude = -81.573486328125014,
    SouthEastLatitude = 42.831667202614092,
    SouthEastLongitude = -80.9355926513672 ,
    SouthWestLatitude = 42.831667202614092,
    SouthWestLongitude = -81.573486328125014
};

var hash = request.GetHashCodeOnProperties();
Console.WriteLine(hash);

Console.ReadKey();


public class Request
{
    public double? SouthWestLatitude { get; set; }
    public double? SouthWestLongitude { get; set; }
    public double? NorthEastLatitude { get; set; }
    public double? NorthEastLongitude { get; set; }


    public double? SouthEastLatitude { get; set; }
    public double? SouthEastLongitude { get; set; }
    public double? NorthWestLatitude { get; set; }
    public double? NorthWestLongitude { get; set; }

}
public static class HashCodeByPropertyExtensions
{
    public static int GetHashCodeOnProperties<T>(this T inspect)
    {
        return inspect.GetType().GetProperties().Select(o => o.GetValue(inspect)).GetListHashCode();
    }

    public static int GetListHashCode<T>(this IEnumerable<T> sequence)
    {
        return sequence
            .Where(item => item != null)
            .Select(item => item.GetHashCode())
            .Aggregate((total, nextCode) => total ^ nextCode);
    }
}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You are xoring values without "offset", so this will result in same values canceling each other out (exclusive or is associative and commutative so 42 ^ 77 ^ 42 ^ 77 is equivalent to 42 ^ 42 ^ 77 ^ 77 which is clearly is 0). You can do something like:

public static int GetListHashCode<T>(this IEnumerable<T> sequence)
{
    var hash = 17;
    return sequence
        .Where(item => item != null)
        .Select(item => item.GetHashCode())
        .Aggregate(hash, (total, nextCode) => unchecked(total*23 + nextCode));
}

Or use System.HashCode (available since .NET Core 2.1) to perform aggregation:

public static int GetListHashCode<T>(this IEnumerable<T> sequence)
{
    var hashCode = new HashCode();
    return sequence
        .Where(item => item != null)
        .Select(item => item.GetHashCode())
        .Aggregate(new HashCode(), (code, i) =>
        {
             hashCode.Add(i);
             return hashCode;
        })
        .ToHashCode();
}

P.S.

Calculating hashcode should be fast operation, while reflection is usually not very fast approach. Consider using source generators or some dynamic code compilation with expression trees (see for example this or this answers for some inspiration)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading