尽管C#(VS2010 Premium)中存在未使用的本地字符串变量,但代码分析未显示CA1804警告。

5

我有以下代码,它不会产生代码分析(VS2010 Premium)中的CA1804警告(声明的变量未被使用):

...
if( boolVariable )
{
    string errorText = "Bla Bla Bla"; // Never used
    ErrorProvider.SetError( SomeControl, "Some Warning" );
}
else
{
    string errorText = "Acme Acme Acme"; // Used below
    ErrorProvider.SetError( SomeControl, errorText );
}
...

当我删除ErrorProvider.SetError( ... )这些行时,会显示CA1804警告,但为什么在上面的代码示例中没有呢?
(顺便说一下:这段代码本身并不是很好,只是用来说明我的问题。)
有什么想法可能会导致这种行为吗?我猜这可能是因为IL代码被优化了,将声明放在if之外,这反过来意味着警告确实不应该出现在像上面那样的示例中,但我不确定这是否正确。
提前感谢。
G.

它可能会将 string errorText = ... 移到 if 外部,并且无法注意到两个同名变量之间的区别。当您将第一个 errorText 更改为 errorText2 时,它是否仍然失败? - Polynomial
1个回答

4

这是由C#编译器执行的优化导致的。在生成的IL中,变量声明被提升到了if块的外部:

string errorText;
if (boolVariable)
{
    errorText = "Bla Bla Bla";
    this.ErrorProvider.SetError(this.SomeControl, "Some Warning");
}
else
{
    errorText = "Acme Acme Acme";
    this.ErrorProvider.SetError(this.SomeControl, errorText);
}

仅删除第二个SetError调用就足以触发CA1804。
顺便提一下,C#编译器应该对此发出CS0219警告,但您显然忽略了它。如果您对代码质量有丝毫兴趣,我强烈建议将编译器警告视为错误。毕竟您已经在使用Code Analysis了,为什么要在最大限度利用现有工具之前添加另一个筛选工具呢?

谢谢,所以我的猜测是正确的。关于您的CS0219建议 - 我在启用代码分析的情况下无法在VS2010中找到这样的警告(我们项目通常将警告级别设置为4)。在我看来,两者都警告同样的问题(“...声明一个变量,'...',类型为'...',它从未被使用或仅被赋值给...”与“变量'...'被赋值但其值从未被使用。”),或者我在这里漏掉了什么? - Gorgsenegger
我不确定为什么你没有看到编译器警告。这个项目是否特别设置为不使用级别4的警告,即使大多数项目都是这样的?或者这个特定的警告是通过项目配置或#pragma warning disable禁用的?至于CS0219和CA1804关于同一问题的警告,它们的目标是相同的,但它们所处理的数据是不同的(源代码与IL)。正如你已经看到的那样,这可能导致不同的结果。 - Nicole Calinoiu
在我上面的问题中,代码被简化了一点以说明目的。我进行了更多的测试,发现当我在两个地方都将固定字符串分配给“errorText”时,例如[string errorText =“Some fixed string”;],我会收到编译器警告(CS0219)。只要我将其更改为稍微复杂一些的内容,例如[string errorText = string.Format(“Some variable:{0}”,“abc”);],编译器警告就会消失,并且只发出代码分析警告(如果实际运行代码分析)。我不理解这种行为。 - Gorgsenegger
1
@Gorgsenegger 我刚刚看到这个,注意到CA1804信息文章上有一个注释,它说:“只有在变量值是编译时常量时,编译器才会生成此警告。将非常量表达式或方法结果分配给局部变量可以更容易地在调试器中观察这些表达式。它还使结果可达,防止垃圾回收器在该变量可达时进行垃圾回收。” - Quintin Willison
1
@Gorgsenegger 我刚刚看到这个,注意到CA1804信息文章上有一条注释,指出_"编译器只在变量值为编译时常量时生成此警告。将非常量表达式或方法结果分配给局部变量可以更容易地在调试器中观察这些表达式。它还使结果可达,防止在该变量可达时进行垃圾回收。"_ - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接