Почему Решарпер думает, что IPrincipal.Identity никогда не будет нулевым?

Resharper 8, работающий в VS2010, говорит мне, что я могу удалить чек на principal.Identity != null:

введите описание изображения здесь

Я предполагаю, что это потому, что в коде для IPrincipal есть атрибут NotNull или что-то скрывающееся, но довольно просто написать собственную реализацию IPrincipal, которая возвращает нулевой идентификатор:

void Main() {
    var foo = new FooPrincipal();
    Console.WriteLine(foo.Identity == null ? "Yep!" : "Not Null");
}

class FooPrincipal : IPrincipal {
    public IIdentity Identity { get; set; }
    public bool IsInRole(string role) { return(false); }
    public FooPrincipal() {}
}

Как Resharper может знать, что IPrincipal, переданный в этот метод, не будет одним из моих FooPrincipal, которые возвращают нулевые идентификаторы?

РЕДАКТИРОВАТЬ: Хорошо, вот полный случай воспроизведения, где Resharper на самом деле призывает вас писать код, который взрывается в производстве...

using System;
using System.Security.Principal;

namespace ResharperPrincipalTest {
    class Program {
        static void Main(string[] args) {
            var p = new TestPrincipal();
            var isJeff = IsUserCalledJeff(p);
            Console.WriteLine(isJeff);
        }

        static bool IsUserCalledJeff(IPrincipal principal) {
            if (principal != null) {
                if (principal.Identity == null) throw(new Exception("Resharper says this will never happen!"));
                return (principal.Identity.Name == "jeff");
            }
            return false;
        }
    }

    class TestPrincipal : IPrincipal {
        public bool IsInRole(string role) {
            return (false);
        }

        public IIdentity Identity { get; set; }
    }
}

и скриншот с VS2010, показывающий "полезную" подсветку Решарпера...

введите описание изображения здесь

и, конечно же, когда вы нажимаете F5, программа выдает исключение. Я бы сказал, что это дает ответ на мой первоначальный вопрос "потому что Решарпер не прав":)

РЕДАКТИРОВАТЬ 2: Отчет об ошибке Resharper подал на http://youtrack.jetbrains.com/issue/RSRP-398551

3 ответа

Я также могу воспроизвести это с VS2010 и R# 7.1 (используя.NET Framework 4.0)

Это вызвано внешними аннотациями Решарпера. По какой-то причине вы можете найти следующее утверждение в файле:

Resharper_Install_Folder\ v7.1 \ Bin \ ExternalAnnotations.NETFramework \ mscorlib \ 4.0.0.0.Contracts.xml

  <member name="P:System.Security.Principal.IPrincipal.Identity">
    <attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
  </member>

Это означает, что любое свойство IPrincipal.Identity НИКОГДА не будет нулевым. Хотя это может быть верно для стандартных реализаций Microsoft IPrincipal, это не всегда означает, что это будет верно для пользовательских реализаций, подобных вашей.

Я удалил строки выше из внешнего файла аннотаций, и проблема исчезла.

Но я вижу, что ваше сообщение об ошибке привело к исправлению для версии 8.2.0.2713, так что это может быть решено этим. Если нет, вы всегда можете удалить строки выше из файла аннотаций, и ваша проблема также должна быть решена.

Решарпер ожидает, что если метод будет выполнен, параметр "IPrincipal principal" не является нулевым, поэтому проверка для!= ноль будет устаревшей в глазах Resharpers

Решарпер не может знать, отправляете ли вы "FooPrincipal" в качестве параметра к Методу.

До обновления вашего вопроса и на основе предоставленного вами фрагмента кода можно подумать, что R# был достаточно умен, чтобы понять, что:

Теперь, если вы можете произвести как предупреждение, так и NullReferenceExceptionМожно предположить, что это ошибка в R#.

Другие вопросы по тегам