2015-06-22 11 views
2

我们有一个项目,我们使用StyleCop和代码分析来验证代码的结构。我们已将警告视为两种机制的错误。为什么在C#项目中进行/优化会生成更多的代码分析警告,而不是启用此功能?

然而,我们发现了一种我们无法解释的平庸行为。我们有一个调试和发布配置。在我们的调试配置中,我们没有得到一个CA警告,而在我们的发布配置中收到此警告。我们开始考虑这两种配置之间的差异,并且我们发现优化复选框是为什么我们在发布期间得到此警告但不在调试过程中的差异。

我们有以下配置。

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> 
    <DebugSymbols>true</DebugSymbols> 
    <DebugType>full</DebugType> 
    <Optimize>false</Optimize> 
    <OutputPath>bin\Debug\</OutputPath> 
    <DefineConstants>DEBUG;TRACE</DefineConstants> 
    <ErrorReport>prompt</ErrorReport> 
    <WarningLevel>4</WarningLevel> 
</PropertyGroup> 
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> 
    <DebugType>pdbonly</DebugType> 
    <Optimize>true</Optimize> 
    <OutputPath>bin\Release\</OutputPath> 
    <DefineConstants>TRACE</DefineConstants> 
    <ErrorReport>prompt</ErrorReport> 
    <WarningLevel>4</WarningLevel> 
</PropertyGroup> 

当我们将优化值设置为true以进行调试时,我们还会发出CA警告。当我们将此设置为false时,警告消失。这也适用于警告CA1806。无论优化值如何,其他CA警告都能正确显示。

触发此警告的代码是以下代码。这只是测试代码,但它模拟了我们的真实情况。一个分配了默认值但从未在任何代码中使用的变量。

public CourseService(IOrtContext context) 
{ 
    this.context = context; 
    var defaultDate = new DateTime(1900, 1, 1); 
} 

那么,有没有人知道为什么CA1806显示取决于是否启用优化?

+0

警告是合法的,因为文档说它是在创建新对象时触发的,但从未使用*。在调试模式下,您是否正面使用'defaultDate'也不会使用? –

+0

该警告确实是合法的。我预计它也会发生在这个测试代码中,但通过上面的调试配置,这个警告不会出现。我确定这个defaultDate不用于任何调试模式代码。上面的代码是我正在使用的确切代码。这个变量在构造函数中作为范围(用于测试),并在构造函数中作为最后一行。 –

回答

0

我认为这是因为优化器完全忽略了分配到defaultDate

在调试模式下,一个新的DateTime被实例化并分配给defaultDate局部变量:

var defaultDate = new DateTime(1900, 1, 1); 

分配被认为是在DateTime实例的“使用”,所以CA1806不提高,甚至如果defaultDate随后不使用。

在另一方面,优化elides在释放模式中的分配(和局部变量):

/* var defaultDate = */ new DateTime(1900, 1, 1); 

因此DateTime实例不被认为是“已使用”了,并CA1806上升。

0

在这里随意扔石头...调试的简单代码:http://goo.gl/8TXmE9和版本:http://goo.gl/XRBfQp

在调试模式下,本地变量的生存期是“扩展”的,直到方法结束,以便它们更易于调试。在发布模式下,这不会发生。变量被大量释放。如果您在调试模式或释放模式下编译程序并尝试调试它,则可以看到它...在释放模式下,有时某些变量无法访问,因为它们已经结束了它们的生命周期。

这可以在释放IL代码可看到:

IL_0007: newobj instance void [mscorlib]System.DateTime::.ctor(int32, int32, int32) 
IL_000c: pop 

new DateTime()返回的是pop PED出栈的立即。 CA1806可以轻松检测到它。

在调试模式下,该值不会弹出堆栈。分析检查它是否在某处使用会相当复杂,可能还没有完成。

相关问题