在VS2010中运行的Resharper 8告诉我可以删除对principal.Identity != null
的检查:
我假设这是因为在IPrincipal的代码中有一个NotNull属性或潜伏的东西,但编写自己的IPrincipal实现很容易返回null身份:
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错误报告
答案 0 :(得分: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属性都不会为null。 虽然对于IPrincipal的默认Microsoft实现可能也是如此,但这并不总是意味着它会适用于像您这样的自定义实现。
我从外部注释文件中删除了上面的行,问题就消失了。
但是我看到您的错误报告导致版本8.2.0.2713的修复,所以它可能会被解决。如果没有,你总是可以从注释文件中删除上面的行,你的问题也应该解决。
答案 1 :(得分:0)
Resharper期望如果执行该方法,参数"IPrincipal principal"
不为空,那么在Resharpers Eyes中检查!= null将会过时
Resharper无法知道您是否正在向方法发送"FooPrincipal"
参数。
答案 2 :(得分:0)
在更新问题之前并根据您提供的代码片段,可以认为R#足够聪明,可以理解:
IsOverride
是私有的,因此无法在您的课程外(通常)调用GenericPrinciple
等具体实施来调用(见https://stackoverflow.com/a/13053981/870604)null
现在,如果您同时发出警告和NullReferenceException
,可以认为它是R#中的错误。