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
和特定值一起使用的启发式是不同的。
我有这个代码:
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
和特定值一起使用的启发式是不同的。