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

3

11

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

Omniscience answered 5/12, 2013 at 12:26 Comment(4)
"Resharper 8 running in VS2010" Does R# 8 work with VS2010? jetbrains.com/resharper/documentation/… If so, I'm well happy because I thought I couldn't use it for VS2012, VS2010 :)Telephotography
@Dylan can you make it break? if yes, then its a mistake on Resharpers partTrudey
Related: #13054365Kerstinkerwin
Have you tried your FooPrincipal class? Does R# behaves differently with it?Kerstinkerwin
D
2

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.

Dorseydorsiferous answered 7/5, 2014 at 19:26 Comment(0)
U
0

Resharper expects that if the method is executed the Parameter "IPrincipal principal" is not null, so a check for !=null would be absolete in Resharpers Eyes

Resharper can't know if you are sending a "FooPrincipal" as parameter to the Method.

Update answered 5/12, 2013 at 12:36 Comment(1)
If what you are saying is correct, then why doesn't Resharper mark the statement principal != null as obsolete?Rabush
K
0

Before the update to your question and based on the piece of code you provided, one can think R# was smart enough to understand that:

Now, if you can produce both a warning and a NullReferenceException, one can assume it's a bug in R#.

Kerstinkerwin answered 5/12, 2013 at 14:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.