The most efficient way to get a hashed object for an arbitrary set of keys (arbitrary data type)

I have a method that should be able to accept an arbitrary number of data fields, somehow combine them into a hashed object, and then put this object in a dictionary for further search.

So far, the best algorithm I've come up with is to take ToHashCode () for each field, and then attach the resulting hash codes to the string using some sort of delimiter character (like "|"), and then use this in The result is a string as a unique key for the dictionary.

Does anyone know a more efficient way to do this? I thought there might be a way to take the hash code of each field and perform some mathematical operation to combine them into a unique number of hashed numbers, but that was just an assumption.

Thanks for any help.

EDIT: I think people may be confused about what I mean. Tuples will not work in this situation, because I need an arbitrary number of fields that will be combined into one hash object. The number of fields is known only at run time, and not at design time.

Another solution related to the mathematical combination of all hash codes into a new hash code will also not work, because I need an object that can be used as a key in a dictionary. I believe that using a hash code as a key in a dictionary is very dangerous.

EDIT 2: After thinking about this, I think my original solution is not very good. In the extreme case, when there is one field, my decision has degenerated into putting a lowercase version of the hash code in the dictionary.

I think perhaps the best solution is to create a new type that will list in its constructor and implement GetHashCode (). The GetHashCode () function then breaks through each value of the enumerated and executes the usual type of battery logic in hash code functions. This way an object can get stuck in a dictionary, hashset, etc. And behave as you expected.

+3
4

, , IEnumerable, - .

ValueAwareEnumerable, IEnumerable. . GetHashCode() Equals(), . GetHashCode :

public override int GetHashCode()
{
    unchecked
    {
        int hash = 983;
        foreach (var item in _wrappedEnumerable)
           if(item != null)
              hash = hash * 457 + item.GetHashCode();
        return hash;
    }
}

:

 public override bool Equals(object obj)
 {
     if (ReferenceEquals(null, obj)) return false;
     if (ReferenceEquals(this, obj)) return true;
     if (obj.GetType() != typeof (ValueAwareEnumerable<T>)) return false;
     return Equals((ValueAwareEnumerable<T>) obj);
 }

 public bool Equals(ValueAwareEnumerable<T> other)
 {
     if (ReferenceEquals(null, other)) return false;
     if (ReferenceEquals(this, other)) return true;

     return _wrappedEnumerable.SequenceEqual(other);                               
 }

, . , , GetHashCode() Equals() .

, - :

public static IEnumerable<T> ToValueAwareEnumerable<T>(this IEnumerable<T> enumerable)
{
   return new ValueAwareEnumerable<T>(enumerable);
}

, :

var dictionary = new Dictionary<IEnumerable<int>>();
var veryImportantNumbers = new[] { 5, 8, 13, 20, 3, 100, 55, -5, 0 };
dictionary[veryImportantNumbers.ToValueAwareEnumerable()] = "Pastrami";

, IEnumerable<Object>.

+1

- Tuple < > - .

var dict = new Dictionary<Tuple<int, string>, MyClass>();
dict[Tuple.Create(myObj.Num, myObj.Str)] = myObj;

, .

+1

, , - - , , .

, , . :

unchecked
{
    int hash = 983;
    hash = hash * 457 + x.GetHashCode();
    hash = hash * 457 + y.GetHashCode();
    hash = hash * 457 + (z != null ? z.GetHashCode() : 0);
    return hash;
}

, - , (, , , ). , Equals, if x.Equals(y), x.GetHashCode() == y.GetHashCode() ( )

0

( ).

, , . :

  • Use Case ( , )
  • , , ( : , . , // , ).
  • , ( ).
  • ?
  • / ?

:
-. . . -, . , . , .
, , -.

, .net, . .

0

All Articles