ReSharper 5.x, HashSet contains() и возможное «нулевое» назначение

Этот код выводит True.

using System;
using System.Collections.Generic;

public class Default
{
    public static void Main(string[] args)
    {
        HashSet<string> foo = new HashSet<string>();
        foo.Add(null);
        Console.WriteLine(foo.Contains(null));
    }
}

Под null в моем вызове Contains() есть синяя волнистая линия со следующим предупреждением:

Возможное «нулевое» присвоение объекту, отмеченному атрибутом «NotNull»

Когда я приостанавливаю ReSharper, предупреждение исчезает.

Почему появляется это предупреждение? Учитывая, что я могу добавить null в HashSet, что мешает мне проверить наличие null в HashSet?

РЕДАКТИРОВАНИЕ: .NET 3.5, VS2010


person lance    schedule 08.12.2010    source источник
comment
ReSharper кажется сломанным. Все остальное выглядит нормально: ваш код работает без исключений, Reflector не показывает ни проверки null, ни какого-либо атрибута NonNull для HashSet‹T›.Add или HashSet‹T›.Contains.   -  person dtb    schedule 08.12.2010
comment
вы действительно должны добавлять Null в HashSet?   -  person Mitch Wheat    schedule 08.12.2010
comment
В моем реальном коде Contains(null) находится в спецификации, которая проверяет, что null, на самом деле, не был добавлен в HashSet в тот момент, когда у разработчика может возникнуть соблазн сделать это.   -  person lance    schedule 08.12.2010
comment
Ошибка в Resharper! Боже упаси! никогда такого раньше не видел...   -  person Coxy    schedule 08.12.2010


Ответы (2)


Я бы сказал, что это ошибка в Resharper. Тип HashSet<T> предназначен для обработки null значений. Это становится очевидным при изучении кода в рефлекторе. В частности, метод InternalGetHashCode, который имеет явную проверку для null и предоставляет хэш-код по умолчанию 0.

Единственный случай, когда это потенциально может вызвать проблему, — это пользовательские экземпляры IEqualityComparer<T>, переданные в HashSet<T>, которые не учитывают значения null. Я бы сказал, что это довольно редко, поскольку проверки null являются частью стандартного шаблона равенства для ссылочных типов в .Net.

Примечание. Чтобы внести ясность, я определенно не призываю людей добавлять null в свою коллекцию. На самом деле я бы поощрял обратное. Просто указываю, что по какой-то причине HashSet<T> явно допускает этот сценарий.

person JaredPar    schedule 08.12.2010
comment
То, что вы можете добавить Null, не обязательно означает, что это хорошая идея;) - person Mitch Wheat; 08.12.2010
comment
@ Митч, я не говорил, что это отличная идея, просто HashSet<T> просто считает, что плохой код должен быть разрешен;) - person JaredPar; 08.12.2010

Я подозреваю, что это может быть связано с тем, что метод HashSet<T>.Contains является реализацией ICollection<T>.Contains.

Другие реализации ICollection<T> могут не допускать пустых значений.

Независимо от того, так это или нет, нет никаких причин, по которым набор правил ReSharper нельзя было бы улучшить, чтобы не помечать это как потенциальную ошибку.

person LukeH    schedule 08.12.2010