2012-01-19 4 views
8

Есть ли какая-либо функция, которая дает мне тот же хэш-код для той же строки?Как я могу создать уникальный хэш-код для строки

У меня возникают проблемы при создании 2 разных строк (но с одним и тем же содержимым), их хэш-код отличается и поэтому неправильно используется в Dictionary.

Я хотел бы знать, что GetHashCode() Функция Dictionary использует, когда ключ является строкой.

Я строй моего так:

public override int GetHashCode() 
{ 
    String str = "Equip" + Equipment.ToString() + "Destiny" + Destiny.ToString(); 
    return str.GetHashCode(); 
} 

Но это производит различные результаты для каждого экземпляра, который использует этот код, несмотря на содержание строки, являющуюся же.

+5

Если строка была на самом деле же, хэш-код будет такой же, тоже. – Joey

+1

Вы уверены, что контент равен? В документации для String.GetHashCode четко указано, что хэш-код будет одинаковым для равных строк: http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx –

+0

Я уверен, что строка .GetHashCode возвращает разные хэши, если вы перезапустите программу. – Tsabo

ответ

13

Ваше название просит одно (уникальных хэш-кодов) ваше тело просит что-то другое (согласующиеся хэш-коды).

Вы утверждаете:

У меня возникают проблемы при создании 2 различных строк (но с тем же содержанием), их хэш-код отличается, и поэтому не используется правильно в Словаре.

Если строки действительно имеют то же содержание, что просто не произойдет. Ваша диагностика как-то не так. Проверьте непечатаемые символы в ваших строках, например, трейлинг Unicode «нулевые» символы:

string text1 = "Hello"; 
string text2 = "Hello\0"; 

Здесь text1 и text2 может печатать так же, как в некоторых контекстах, но я надеюсь, что они имеют разные хэш-коды ,

Обратите внимание, что хэш-коды не гарантированно быть уникальным и не может быть ... есть только 2 возможных хэш-коды вернулся из GetHashCode, но более 2 возможны различные строки ,

Также обратите внимание, что то же самое содержание не гарантированно производить тот же хэш-код на различных прогонов, даже одного и того же исполняемого файла - вы не должны быть сохраняющиеся хэш-код в любом месте. Например, я считаю, что 32-разрядные .NET 4 и 64-разрядные .NET 4 CLR создают разные хэш-коды для строк. Однако ваше утверждение о том, что значения не сохраняются правильно в Dictionary, предполагает, что это в рамках одного процесса - где все должно быть последовательным.

Как уже отмечалось в комментариях, вполне возможно, что вы неправильно отменили Equals. Я бы также предположил, что ваш подход к созданию хэш-кода невелик. Мы не знаем, какие типы Equipment и Destiny есть, но я хотел бы предложить, вы должны использовать что-то вроде:

public override int GetHashCode() 
{ 
    int hash = 23; 
    hash = hash * 31 + Equipment.GetHashCode(); 
    hash = hash * 31 + Destiny.GetHashCode(); 
    return hash; 
} 

Это подход, который я обычно использую для хэш-кодов.Equals будет выглядеть примерно так:

public override bool Equals(object other) 
{ 
    // Reference equality check 
    if (this == other) 
    { 
     return true; 
    }   
    if (other == null) 
    { 
     return false; 
    } 
    // Details of this might change depending on your situation; we'd 
    // need more information 
    if (other.GetType() != GetType()) 
    { 
     return false; 
    } 

    // Adjust for your type... 
    Foo otherFoo = (Foo) other; 

    // You may want to change the equality used here based on the 
    // types of Equipment and Destiny 
    return this.Destiny == otherFoo.Destiny && 
      this.Equipment == otherFoo.Equipment; 
} 
+0

Оборудование и судьба оба перечислены – RagnaRock

+1

@ RagnaRock: Вправо - в этом случае это должно быть хорошо. Это в классе или структуре? И если это класс, он запечатан? В любом случае, я сомневаюсь, что вы сможете воспроизвести предполагаемое несоответствие хеширования. –

+0

проблема была в методе равных, я думал, что не должен был ее переопределять, как только я это сделал, он работал как ожидалось – RagnaRock

Смежные вопросы