ホームページ  >  記事  >  バックエンド開発  >  C# GetHashCode の実装方法

C# GetHashCode の実装方法

黄舟
黄舟オリジナル
2017-02-28 11:46:552061ブラウズ

プロジェクトでハッシュ テーブルを使用する場合、GetHashCode をオーバーライドする必要がある場合があります。一般的なアプローチは次のとおりです:

バージョン 1:
ヘルパーを実装し、型 T を渡し、この型のハッシュコードを返します。関数のロジックは非常に単純で、null チェックを行うだけです。obj が空でない場合は、obj のハッシュ コードが直接使用されます。

public class HashHelper
{
	private int _seed = 17;	
	public int Hash<T>(T obj)
	{
		// why 31?
		// http://www.php.cn/
		// shortly, to reduce the conflict of hashing key&#39;s distrabution
		return 31 * _seed + ((obj == null) ? -1 : obj.GetHashCode());
	}
}


なぜマジックナンバー 31 を使用するのでしょうか? 素数積を使用すると、相対的に一意性が向上し、ハッシュ キー値の割り当ての際の競合が軽減されますが、31 はコンパイラの最適化を考慮したものです (実質的に i< https://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/
実装バージョン 2:
このクラスは次のように拡張できます。流暢なインターフェイス。さまざまな型をハッシュできます。値型の場合、オーバーロードの重要性はボックス化を軽減することであり、コレクションまたはジェネリックの場合、外部呼び出しをより自然で読みやすくすることです。

public class HashFluent
{
	private int _seed = 17;	
	private int _hashContext;
	
	public HashFluent Hash<T>(T obj)
	{
		// why 31?
		// http://www.php.cn/
		// shortly, to reduce the conflict of hashing key&#39;s distrabution
		_hashContext = 31 * _seed + ((obj == null) ? -1 : obj.GetHashCode());
		return this;
	}
	
	public HashFluent Hash(int? value)
	{
		_hashContext = 31 * _seed + ((value == null) ? -1 : value.GetHashCode());
		return this;
	}
	
	public HashFluent Hash(IEnumerable sequence)
	{
		if (sequence == null)
		{
			_hashContext = 31 * _hashContext + -1;
		}
		else
		{
			foreach (var element in sequence)
			{
				_hashContext = 31 * _hashContext + ((element == null) ? -1 : element.GetHashCode());
			}
		}
		return this;
	}
	
	public override int GetHashCode (){
		return _hashContext;
	}
		
	// add more overridings here ..
	// add value types overridings to avoid boxing which is important
}

上記は C# GetHashCode の実装の内容です。その他の関連内容については、PHP 中国語 Web サイト (www.php.cn) をご覧ください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。