2011-11-08 70 views
0

我的目標是創建一個具有以下要求的方法:如何爲任意類型的對象生成一個唯一的long(散列)?

  • 輸出應該在不同的應用程序域是一致的(但正在運行的.NET Framework的版本相同)不同類型的
  • 對象應不會產生相同的散列
  • 衝突是極不可能
  • 的方法將相當頻繁調用,所以應該不會太慢

個那我考慮一下類似的實現:

private static long GenerateHash<TKey>(TKey key) 
{ 
    long typeHash = typeof(TKey).GetHashCode(); 
    long keyHash = key.GetHashCode(); 
    return (typeHash << 32) + keyHash; 
} 

private static long GenerateHash<TKey>(TKey key) 
    { 
     using (var stream = new MemoryStream()) 
     { 
      var formatter = new BinaryFormatter(); // Or other serialiser 
      formatter.Serialize(stream, key); 
      stream.Seek(0, SeekOrigin.Begin); 
      var hashAlgorithm = new SuitableHashAlgorithm(); // Not real class, need to find/write a hash algorithm that can compute 64 bit hashes... 
      var hash = hashAlgorithm.ComputeHash(stream); 
      return BitConverter.ToInt64(hash, 0); 
     } 
} 

注意,關鍵的可能是NULL的含量不考慮。

這些實現的任何意見和潛在的缺陷以及任何其他可能的缺陷都會受到歡迎。

感謝

+2

在應用程序域之間不保證定期'GetHashCode()',並且'BinaryFormatter'不能保證產生相同的結果(最近有一些反例在這裏,相同的數據可能產生不同的輸出) - 它只是爲了讓您的數據完整無損,而不是提供一致的數據佈局。 –

+0

你想要一些可以在任何對象上使用的泛型嗎?我認爲反射會對你想要的太重。 – Tudor

+0

我想你最好看看這篇文章[HashCode指南](http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx ) – V4Vendetta

回答

1

看來,要求不能用規定的方法簽名來滿足,感謝大家的意見,特別是@Marc Gravell。

我將介紹一個合適的接口,它具有所有鍵將實現的UniqueId屬性。

我一直希望避免這種情況,以保持向後兼容性,但嘿嘿,你不能總是得到你想要的!

相關問題