ReSharper 找不到无法访问的代码

ReSharper can´t find unreachable code

我有这个代码:

Assert.IsTrue(datasetMetadata1 != null && datasetMetadata1.Length == 5);
Assert.IsTrue(datasetMetadata2 != null && datasetMetadata2 .Length == 11);

if ((datasetMetadata1 == null || datasetMetadata1.Length != 5) ||
(datasetMetadata2 == null || datasetMetadata2 .Length != 11)
{ 
    /* do something */ 
}

ReSharper 通过删除冗余(因为总是 true)表达式 == null 并将 if 语句反转为类似于以下内容的语句来简化:

if ((datasetMetadataPunktort.Length == 5) && (datasetMetadataFlurstueck.Length == 11)) 
    return

然而对我来说,即使这个检查似乎也毫无意义,而且很容易被忽略,因为条件总是正确的。所以我想知道为什么 ReSharper 检测到针对 null 的过时检查,但没有检测到其余的检查。

我是否遗漏了任何检查失败的情况?

解释我的评论:

To my mind, the thing is the following : Each time you test your value, you make a call to the getter. Resharper doesn't know if your actual getter modifies or not your value. It could be possible that the first time you call the getter it returns 5 and increments the value by 6. So next time you will have 11 returned.

我创建了这个小型控制台应用程序作为示例:

这个类包含带有特殊 getter 的参数。

public class TestClass
{
    private int _length;

    public int Length
    {
        get
        {
            var localLength = _length;
            _length += 6;
            return localLength;
        }
        set { _length = value; }
    }

    public TestClass(int length)
    {
        this._length = length;
    }
}

此class用于测试目的:

  class Program
{
    static void Main(string[] args)
    {
        var testObject = new TestClass(5);
        if ((testObject.Length == 5) && (testObject.Length == 11))
        {
            Console.WriteLine("TRUE");
        }
        else
        {
            Console.WriteLine("FALSE");
        }
        Console.Read();

    }
}

我们有以下输出:

TRUE

我同意这个 class 非常特殊,目的是让条件有效,但它仍然表明这种情况是可能的。

总的来说,由于在每个条件之间调用getter,值可以改变,所以调用不是多余的。

除了 Visalievski 的回答,让我再补充一个——更简单的——例子:

int i = 5;
if (i != 5)
{
    // do something
}

使用此代码段,ReSharper 不会检测无法访问的代码。

但让我对该代码做一个小改动:使 i 保持不变。

const int i = 5;
if (i != 5)
{
    // do something
}

现在,ReSharper 抱怨无法访问代码,我在 VS2015 中收到编译器警告 CS0162。

所以在处理特定值时,ReSharper 和编译器都会询问该值是否保证为常量。因此,我得出结论,与 null 和特定值一起使用的启发式是不同的。