ReSharper: как удалить предупреждение "Возможное" System.NullReferenceException "

Вот кусок кода:

IUser user = managerUser.GetUserById(UserId);
if ( user==null ) 
    throw new Exception(...);

Quote quote = new Quote(user.FullName, user.Email);

Здесь все хорошо. Но если я заменю строку "if" на следующую:

ComponentException<MyUserManagerException>.FailIfTrue(user == null, "Can't find user with Id=" + UserId);

где реализация функции следующая:

public abstract class ComponentException<T> : ComponentException
        where T : ComponentException, new()
{
    public static void FailIfTrue(bool expression, string message)
    {
        if (expression)
        {
            T t = new T();
            t.SetErrorMessage(message);
            throw t;
        }
    }
    //...
}

Затем ReSharper генерирует мне предупреждение: возможно "System.NullReferenceException", указывающее на 1-е использование объекта "user".

Q1. Почему это порождает такое исключение? Насколько я вижу, если user==null то будет сгенерировано исключение, и выполнение никогда не достигнет точки использования.

Q2. Как убрать это предупреждение? Пожалуйста, обратите внимание: 1. Я не хочу подавлять это предупреждение комментариями (у меня будет много подобных частей и я не хочу превращать мой исходный код в 'закомментированный мусор); 2. Я не хочу изменять настройки ReSharper, чтобы изменить эту проблему с предупреждения на "предложение" в "подсказке".

Благодарю.

Любые мысли приветствуются!

PS Я использую Resharper 5.1, MVSV 2008, С#

Ответ 1

Q1: Поскольку Resharper не анализирует путь. Он просто видит возможную ссылку null и флаги.

Q2: Вы не можете не делать того, что вы уже предоставили.

Ответ 2

Resharper рассматривает только текущий метод для своего анализа и не рекурсивно анализирует другие методы, которые вы вызываете.

Однако вы можете перенаправить Resharper и дать ему метаинформацию о некоторых методах. Он знает, например, об "Assert.IsNotNull(a)" и будет учитывать эту информацию для анализа. Можно создать внешний файл аннотаций для Resharper и предоставить ему дополнительную информацию о некоторой библиотеке, чтобы сделать ее анализ лучше. Возможно, это может предложить вам способ решить вашу проблему.

Более подробную информацию можно найти здесь.

Пример, показывающий, как он используется для библиотеки Microsoft.Contracts, можно найти здесь.

Ответ 3

Новый ответ в старой почте...

Вот небольшой пример моего кода относительно использования CodeContract через ContractAnnotation с Resharper:

    [ContractAnnotation("value:null=>true")]
    public static bool IsNullOrEmpty(this string value)
    {
        return string.IsNullOrEmpty(value);
    }

Это очень просто... если вы найдете панировку в лесу. Вы также можете проверить другие случаи.

Хороший день

Ответ 4

Вы знаете (или ожидаете), что этот код будет генерировать исключение, если существует нулевая ссылка:

ComponentException<MyUserManagerException>.FailIfTrue([...]);

Однако, поскольку контракта нет, указав это, ReSharper должен предположить, что это обычный вызов метода, который может возвратиться без каких-либо исключений в любом случае.

Сделайте этот метод реализацией контракта ReSharper или как простой метод обхода (который влияет только на режим отладки, поэтому не влияет на производительность для режима выпуска) сразу после вызова FailIfTrue:

Debug.Assert(user != null);

Это избавит вас от предупреждения, и в качестве дополнительного бонуса выполните проверку времени выполнения в режиме отладки, чтобы убедиться, что условие, принятое вами после вызова FailIfTrue, действительно выполнено.

Ответ 5

Это вызвано движком Resharper. Это "возможное исключение NullReferenceException" происходит потому, что кто-то (возможно, в Resharper) объявил/сконфигурировал где-то аннотацию к методу.

Вот как это работает: ReSharper NullReferenceException Анализ и его контракты

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

При обнаружении ошибки вы должны сообщить об этом в JetBrains, и они будут обновлять аннотации в следующей версии. Они привыкли к этому.

Между тем, вы можете попытаться исправить это самостоятельно. Подробнее читайте в статье:)

Ответ 6

Пожалуйста, проверьте, есть ли у вас какой-либо пользователь == ноль, если проверка выше указанного кода. Если есть, то ReSharper считает, что переменная "может быть нулевой", поэтому рекомендует вам использовать проверку/утверждение перед обращением к ней. В некоторых случаях это единственный способ, которым ReSharper может угадать, может ли переменная быть нулевой или нет.