2016-01-12 2 views
2

Просто хотят, чтобы кто-нибудь подтвердить свое мышление, я пробовал разные комбинации из переопределения Равно и GetHashCode в Foo класса:C# HashSet проверяет дубликат на Equals, а затем на GetHashCode?

class Foo 
{ 
    static int n; 
    public override bool Equals(object obj) 
    { 
     return true; 
     //return false; 
    } 
    public override int GetHashCode() 
    { 
     return 0; 
     //return n++; 
    } 
} 

то результат теста показал:

static void Main(string[] args) 
    { 
     HashSet<Foo> set = new HashSet<Foo>(); 
     Foo f1 = new Foo(); 
     Foo f2 = new Foo(); 

     Console.WriteLine(f1.Equals(f2)); 
     set.Add(f1); 
     Console.WriteLine(set.Contains(f2)); 
     Console.ReadLine(); 
    } 
  1. Когда Equals истинно, Contains определяется GetHashCode;
  2. Когда Equals false, Contains всегда false.

Так Содержит определяется Равных затем GetHashCode, я прав?

+5

Вы можете легко подтвердить свое мышление, добавив 'Console.WriteLine' к каждому переопределенному методу, чтобы увидеть порядок, в котором они отображаются. – ray

ответ

5

Другой путь. Вызывается первый GetHashCode(). Это используется для предоставления хеш-кода (отсюда и имя), который используется для определения того, где внутри объект должен храниться.

Нет никакой гарантии, что хеш-коды будут уникальными (и, кроме того, он будет уменьшен дополнительно), поэтому может быть более одного объекта, хранящегося с одним и тем же хэшем (чем больше, тем хуже производительность, но это другое дело). Таким образом, после нахождения возможных совпадений Equals используется для подтверждения соответствия.

Так Contains зависит от GetHashCode() сначала, а затем от Equals().

Для того, чтобы работать в тандеме, вы должны всегда переопределять его, если вы переопределяете другой, и всегда переопределяете свой GetHashCode() таким образом, чтобы любые два объекта, которые рассматривали бы друг друга Equal(), будут иметь одинаковый код.

+0

И самый простой способ обеспечить, чтобы два объекта, которые считали друг друга равными, имели один и тот же хеш-код, как правило, чтобы ваш метод 'Equals()' вызывал ваш метод GetHashCode(). –

+0

Предоставление цитаты из соответствующих документов (и ссылок) для MSDN идеально подходит для лучшего документирования вашего сообщения. Это также должно помочь другим проверить, что это документированное поведение, а не детали реализации, которые могут отличаться в разных средах/реализации (например, Mono). – ray

+1

@JoelCoehoorn - Как это работает? – Enigmativity

Смежные вопросы