11

在 VS2010 中运行的 Resharper 8 告诉我我可以删除检查principal.Identity != null

在此处输入图像描述

我假设这是因为 IPrincipal 的代码中有一个 NotNull 属性或潜伏的东西,但是编写自己的返回 null 标识的 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 不会是我的返回 null 身份的 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 的屏幕截图显示 Resharper 的“有用”突出显示......

在此处输入图像描述

果然,当你按下 F5 时,程序会抛出异常。我想说这可以回答我原来的问题“因为 Resharper 是错误的”:)

编辑 2:在http://youtrack.jetbrains.com/issue/RSRP-398551提交的 Resharper 错误报告

4

3 回答 3

2

我还可以使用 VS2010 和 R# 7.1(使用 .NET Framework 4.0)重现此问题

这是由 Resharper 的外部注释引起的。出于某种原因,您可以在文件中找到以下语句:

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 属性永远不会为空。虽然这可能适用于 IPrincipal 的默认 Microsoft 实现,但这并不总是意味着它适用于像您这样的自定义实现。

我从外部注释文件中删除了上面的行,问题就消失了。

但我看到您的错误报告导致版本 8.2.0.2713 的修复,所以它可能会被解决。如果不是,您总是可以从注释文件中删除上面的行,您的问题也应该得到解决。

于 2014-05-07T19:26:09.900 回答
0

Resharper 预计,如果执行该方法,则 Parameter"IPrincipal principal"不为 null,因此在 Resharpers Eyes 中对 !=null 的检查将被废弃

Resharper 无法知道您是否将"FooPrincipal"作为参数发送到方法。

于 2013-12-05T12:36:12.127 回答
0

在更新您的问题之前,根据您提供的一段代码,可以认为 R# 足够聪明,可以理解:

  • 由于IsOverride是私有的,它不能(通常)在你的班级之外被调用
  • 因为没有人称它为,或者它只用一个具体的实现来调用,例如GenericPrinciple(见https://stackoverflow.com/a/13053981/870604
  • 那么永远不可能null

现在,如果您可以同时生成警告和警告NullReferenceException,则可以认为这是 R# 中的错误。

于 2013-12-05T14:35:25.157 回答