Create Hash Value on a List?

前端 未结 2 1160
南旧
南旧 2021-01-07 22:44

I have a List with 50 instances in it. Each of the instances has 1 or 2 unique properties, but in a way they are all unique because there is

2条回答
  •  伪装坚强ぢ
    2021-01-07 23:05

    Does the hash have to be representative of the list's contents? In other words will you use the hash to determine potential equality? If not then just create a new Guid and use that.

    If the identifier does need to represent the contents of the list then you can either generate a hashcode based on the contents of the list (this will be inefficient as you will be unable to cache this value as the list's contents may change) or forgo the hash altogether and use Enumerable.SequenceEquals to determine equality.


    Here is an example of how I would implement getting a hash code for a List. First of all, if you are going to get a hash code for a particular object your really ought to make sure that object will not change. If that object does change then your hash code is no longer any good.

    The best way to work with a list that can be "frozen" (meaning no items added or removed after a certain point) is to call AsReadOnly. This will give you a ReadOnlyCollection. The implementation below hinges on a ReadOnlyCollection just to be safe so keep that in mind:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    
    class Example
    {
        static void Main()
        {
            var seqOne = new List { 1, 2, 3, 4, 5, 6 };
            var seqTwo = new List { 6, 5, 4, 3, 2, 1 };
    
            var seqOneCode = seqOne.AsReadOnly().GetSequenceHashCode();
            var seqTwoCode = seqTwo.AsReadOnly().GetSequenceHashCode();
    
            Console.WriteLine(seqOneCode == seqTwoCode);
        }
    }
    
    static class Extensions
    {
        public static int GetSequenceHashCode(this ReadOnlyCollection sequence)
        {
            return sequence
                .Select(item => item.GetHashCode())
                .Aggregate((total, nextCode) => total ^ nextCode);
        }
    }
    

    Oh, one last thing - make sure that your MyRichObject type has a good GetHashCode implementation itself otherwise your hash code for the list will potentially yield a lot of false positives upon comparison.

提交回复
热议问题