Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Resharper think IPrincipal.Identity will never be null?

Resharper 8 running in VS2010 is telling me I can remove a check for principal.Identity != null:

enter image description here

I'm assuming this is because there's a NotNull attribute or something lurking in the code for IPrincipal, but it's quite easy to write your own IPrincipal implementation that returns a null Identity:

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() {}
}

How can Resharper know that the IPrincipal passed into this method isn't going to be one of my FooPrincipals that return null identities?

EDIT: Ok, here's a full reproduction case where Resharper actually encourages you to write code that blows up in production...

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; }
    }
}

and the screenshot from VS2010 showing Resharper's 'helpful' highlighting...

enter image description here

and sure enough, when you hit F5 the program throws an exception. I'd say that makes the answer to my original question "because Resharper is wrong" :)

EDIT 2: Resharper bug report filed at http://youtrack.jetbrains.com/issue/RSRP-398551

like image 980
Dylan Beattie Avatar asked Dec 05 '13 12:12

Dylan Beattie


1 Answers

I can also reproduce this with VS2010 and R# 7.1 (using .NET Framework 4.0)

This is caused by Resharper's external annotations. For some reason you can find the following statement in the file :

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>

What this states is that any IPrincipal.Identity property will NEVER be null. While this might be true for the default Microsoft implementations of IPrincipal, this does not always mean it will be true for custom implementations like yours.

I removed the lines above from the external annotations file and the problem goes away.

But I see your bug report resulted in a fix for version 8.2.0.2713, so it might be solved by that. If not you can always remove the lines above from the annotations file and your problem should also be solved.

like image 182
Huron Avatar answered Sep 23 '22 16:09

Huron