For a class to work in a hash table or dictionary, you need to implement GetHashCode()
! I have no idea why it's working in HashSet; I would guess it was just luck.
Note that it's dangerous to use mutable fields for calculating Equals or GetHashCode(). Why? Consider this:
var x = new Int16_2D { a = 1, b = 2 };
var set = new HashSet<Int16_2D> { x };
var y = new Int16_2D { a = 1, b = 2 };
Console.WriteLine(set.Contains(y)); // True
x.a = 3;
Console.WriteLine(set.Contains(y)); // False
Console.WriteLine(set.Contains(x)); // Also false!
In other words, when you set x.a = 3;
you're changing x's hash code. But x's location in the hash table is based on its old hash code, so x is basically lost now. See this in action at http://ideone.com/QQw08
Also, as svick notes, implementing Equals
does not implement ==
. If you don't implement ==
, the ==
operator will provide a reference comparison, so:
var x = new Int16_2d { a = 1, b = 2 };
var y = new Int16_2d { a = 1, b = 2 };
Console.WriteLine(x.Equals(y)); //True
Console.WriteLine(x == y); //False
In conclusion, you're better off making this an immutable type; since it's only 4 bytes long, I'd probably make it an immutable struct.