2012-05-22 5 views
12

Рассмотрим следующий код:нужны разъяснения по смыслу ReSharper NotNullAttribute

public static void Foo() 
    { 
     Bar(null); 
    } 

    public static void Bar([NotNull] string s) 
    { 
     if (s == null) 
      throw new ArgumentNullException("s"); 
    } 

[NotNull] Атрибут используется на Bar сказать абонентам, что s не должен быть пустым. Это отлично работает, и я получаю предупреждение, когда передаю значение null в Bar (Возможное присвоение «null» сущности, помеченной атрибутом «NotNull»).

Но это на самом деле не мешает мне передавать нуль, поэтому Bar еще должен проверить, s имеет значение null. Так почему я также получаю предупреждение на if (s == null) (Выражение всегда неверно)?

Насколько я могу судить, этот атрибут имеет двусмысленный смысл; в зависимости от контекста, это может означать две разные вещи:

  • для вызывающего абонента: не передать нулевой аргумент
  • для вызываемым: этот аргумент не является нулевым

Я правильно использую этот атрибут, или я что-то упускаю?

BTW, я использую Resharper 7 EAP, так что это может быть ошибка; Однако я хочу, чтобы убедиться, что мое использование правильно, прежде чем сообщить его ...


EDIT: просто пытался то же самое с R # 5.1 на рабочем месте; он показывает предупреждение на сайте вызова, но не в методе. Я сообщу об этом на Youtrack Jetbrain.


EDIT2: ошибка сообщила here

+0

Что произойдет, если добавить второго абонента, который проходит что-то другое, чем ' null'? Может быть, что v7 делает более проницательный анализ источника ценности и видит, что в этом случае единственный вызывающий элемент 'Bar' передает' null' ... – AakashM

+0

Кстати, насколько я знаю, семантика этого атрибута * * * только первая из ваши пулевые очки; это заявление этого метода внешнему миру. – AakashM

+0

@AakashM, хорошо, но если он сделал этот анализ, он должен сказать: «выражение всегда истинно», а не всегда false ... Во всяком случае, я попытался добавить вызов с ненулевым значением для s, и он все еще дает такое же предупреждение. –

ответ

3

Насколько я могу сказать, что вы используете его правильно и ReSharper неправильно сказать, что сравнение всегда false. Атрибут [NotNull] - это не более чем документация, и ваш код прав, чтобы дважды проверить входные значения. Решарпер не первый раз сделал неправильное или глупое предложение. Замечательная вещь о JetBrains заключается в том, что у них есть a public bug tracker, где вы можете сообщить об этом и получить обратную связь прямо от разработчиков.

Это сказал (и простите меня, если вы знаете об этом), C# 4.0's Code Contracts делает это легко, предсказуемо и надежно:

Contract.RequiresAlways(s != null); 
+2

По-видимому, он был исправлен в окончательной версии R # 7 –