0

我有这个代码:

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 通过删除多余的(因为 allways true)表达式== null和将if-statement 反转为类似于以下内容来简化它:

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

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

我错过了任何检查失败的情况吗?

4

2 回答 2

1

除了 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和与特定值一起使用的启发式方法是不同的。

于 2016-09-29T08:03:51.793 回答
0

解释我的评论:

在我看来,事情是这样的:每次测试你的值时,你都会调用 getter。Resharper 不知道您的实际 getter 是否修改了您的值。您第一次调用 getter 时可能会返回 5 并将值增加 6。所以下次您将返回 11。

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

该类包含带有特殊 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 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

我同意这个类是非常特殊的,并且是为了使条件起作用而制作的,但它仍然表明这种情况是可能的。

总的来说,它表明由于在每个条件之间调用了getter,因此值可以改变,因此调用不是多余的。

于 2016-09-29T07:51:14.550 回答