2014-03-09 4 views
0

мне нужно определить, какой ключ HashSet является MyClassОпределение HashSet с индивидуальным ключом

public class MyClass 
{ 
    private string m_x; 
    private string m_y; 
    MyClass(string x,string y) 
    { 
     m_x = x; 
     m_y =y; 
    } 
} 

Так что я

HashSet <MyClass> myHash; 
MyClass m = new MyClass("1","123"); 
myHash.Add(m); 
bool isContained = myHash.Contains(m); 

IsContained является false .... Что не так? Что может быть другим контейнером, который позволяет сохранять уникальные ключи? и вернуть ответ, если ключ находится внутри с минимальной сложностью?

+1

Можете ли вы показать фактический код? Это должно выбросить NRE. –

+0

Override * GetHashCode * и * Equals * –

+0

Невозможно воспроизвести, отлично работает для меня. Можете ли вы опубликовать код, который воспроизводит поведение? –

ответ

2

а) Предполагая, что вы не хотите, чтобы сравнить объекты по ссылки, вы должны переопределить GetHashCode и Equals методы 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; 
    } 
} 

б) Вы также можете использовать IEqualityComparer для сравнения ваших объектов, но в этом случае вам понадобятся некоторые общедоступные свойства

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(); 
    } 
} 

Теперь вам нужно только дать компаратор конструктору HashSet в

HashSet<MyClass> myHash = new HashSet<MyClass>(new MyEqualityComparer()); 
1

Просто измените MyClass так он реализует Equals и 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(); 
    } 
} 

Теперь IsContained2 также является true, даже если он не был добавлен в 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! 
Смежные вопросы