LoginSignup
4
1

More than 1 year has passed since last update.

【C#】ValueObject作成時のGetHashCode()のオーバーライドの実装方法

Last updated at Posted at 2022-02-24

前提知識(知っている方はスキップ推奨)

そもそもValueObjectって何?

ざっくりいうと、システム固有のオブジェクト(独自型)です。
値が持つビジネスルールを表現することができます。
詳しくはググってみてください。

そもそもハッシュ関数って何?

入力されたデータを"何らかの値"にして返却する関数です。
"何らかの値"を生成するときは、ある一定のルールに従って行われます。
したがって、同じ値をハッシュ関数に与えると、同じ値が返却されます。
尚、ハッシュ関数が返却する値をハッシュ値と言います。

ValueObjectが単一の値しか持たない場合

プロパティに対してGetHashCode()をするだけでOKです。

public class Id
{
	public int Value { get; set;}
	// ...略
	public override int GetHashCode()
	{
		return Value.GetHashCode();
	}
	// ...略
}

ValueObjectが複数の値を持つ場合

C#7以降の場合tupleを使用する

public class Name
{
	public string First { get; set;}
	public string Last { get; set;}
	// ...略
	public override int GetHashCode()
	{
		return (First, Last).GetHashCode();
	}
	// ...略
}

.NET Standard2.1以降の場合HashCode.Combineを使用する

class Name
{
	public Name(string first, string last)
	{
		First = first;
		Last = last;
	}

	public string First { get; set; }
	public string Last { get; set; }
	// ...略
	public override int GetHashCode()
	{
		return HashCode.Combine(First, Last);
	}
	// ...略
}

その他、自力でやる場合は素数をかけて排他論理和をとる

class Name
{
	public Name(string first, string last)
	{
		First = first;
		Last = last;
	}

	public string First { get; set; }
	public string Last { get; set; }
	// ...略
	public override int GetHashCode()
	{
		return (First.GetHashCode() * 397) ^ Last.GetHashCode();
	}
	// ...略
}

適当にやるとどうなる?

例えば、return First.GetHashCode() ^ Last.GetHashCode();のようにしてしまうと、
値がひっくり返っている場合に同一のハッシュ値となってしまいます。
上述のNameクラスで例えると、
「吉野 葵(よしの あおい)さん」と「葵 吉野(あおい よしの)さん」は別人です。
しかし、return First.GetHashCode() ^ Last.GetHashCode();という実装だと
ただの排他論理和のため、
「吉野 葵(よしの あおい)さん」と「葵 吉野(あおい よしの)さん」のハッシュ値が同一となってしまいます。
説明した上記3つの例では、違うハッシュ値が返ります。

まとめ

  • ValueObjectが単一の値しか持たない場合
    • return Value.GetHashCode();でOK
  • ValueObjectが複数の値を持つ場合
    • tuppleを使う:return (First, Last).GetHashCode();
    • HashCode.Combineを使う:return HashCode.Combine(First, Last);
    • 素数+排他論理和を使う:return (First.GetHashCode() * 397) ^ Last.GetHashCode();

参考文献

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1