Reputation: 10153
I need to define hashset which key is MyClass
public class MyClass
{
private string m_x;
private string m_y;
MyClass(string x,string y)
{
m_x = x;
m_y =y;
}
}
So I have
HashSet <MyClass> myHash;
MyClass m = new MyClass("1","123");
myHash.Add(m);
bool isContained = myHash.Contains(m);
IsContained
is false
....What is wrong?
what could be another container, which allows to save the unique keys? and return the answer if key is inside with minimum complexity?
Upvotes: 0
Views: 765
Reputation: 116138
a) Assuming you don't want to compare the objects by their references, you should override GetHashCode
and Equals
methods of MyClass
HashSet<MyClass> myHash = new HashSet<MyClass>();
MyClass m1 = new MyClass("1", "123");
MyClass m2 = new MyClass("1", "123");
myHash.Add(m1);
bool b = myHash.Contains(m2); //true
public class MyClass
{
private string m_x;
private string m_y;
public MyClass(string x, string y)
{
m_x = x;
m_y = y;
}
public override int GetHashCode()
{
return m_x.GetHashCode() ^ m_y.GetHashCode();
}
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj)) return true;
if (obj == null) return false;
var other = obj as MyClass;
return m_x == other.m_x && m_y == other.m_y;
}
}
b) You can also use IEqualityComparer to compare your objects, But in this case you need some public properties
public class MyClass
{
public string m_x;
public string m_y;
public MyClass(string x, string y)
{
m_x = x;
m_y = y;
}
}
public class MyEqualityComparer : IEqualityComparer<MyClass>
{
public bool Equals(MyClass x, MyClass y)
{
return x.m_x == y.m_x && x.m_y == y.m_y;
}
public int GetHashCode(MyClass obj)
{
return obj.m_x.GetHashCode() ^ obj.m_y.GetHashCode();
}
}
Now, you only need to give the comparer to the HashSet's constructor
HashSet<MyClass> myHash = new HashSet<MyClass>( new MyEqualityComparer());
Upvotes: 2
Reputation: 2598
Just change your MyClass so it implements Equals and GetHashCode:
public class MyClass
{
private string m_x;
private string m_y;
public MyClass(string x, string y)
{
m_x = x;
m_y = y;
}
public override bool Equals(object obj)
{
var typed = obj as MyClass;
if (typed == null) return false;
return typed.m_x == m_x && typed.m_y ==m_y;
}
public override int GetHashCode()
{
return new {m_x, m_y}.GetHashCode();
}
}
Now the IsContained2 also is true, even if it has not been added to the HashSet:
HashSet<MyClass> myHash =new HashSet<MyClass>();
MyClass m = new MyClass("1", "123");
MyClass m2 = new MyClass("1", "123");
myHash.Add(m);
bool isContained = myHash.Contains(m);
bool isContained2 = myHash.Contains(m2); // True!
Upvotes: 1