【问题标题】:If Then Statement Condition Being Ignored With Optimisations OnIf Then 语句条件在优化时被忽略
【发布时间】:2010-06-16 07:50:48
【问题描述】:

if then else 语句的两边都在执行?

我尝试注释掉真实的一面并将条件移动到具有相同结果的单独变量中。但是,如果我将条件显式设置为 1=0 或 1=1,那么 if then 语句将按照我的预期运行。即只执行等式的一侧...

我唯一一次看到这种事情是编译器崩溃并且不再编译(没有明显的迹象表明它不是)但我以相同的结果重新启动了工作室,我清理了解决方案,构建和重建没有改变?

请告诉我我犯的愚蠢错误 如果重要,请使用 vs2005。

    Dim dset As DataSet = New DataSet
    If (CboCustomers.SelectedValue IsNot Nothing) AndAlso (CboCustomers.SelectedValue <> "") Then
        Dim Sql As String = "Select sal.SalesOrderNo As SalesOrder,cus.CustomerName,has.SerialNo, convert(varchar,sal.Dateofpurchase,103) as Date from [dbo].[Customer_Table] as cus " & _
                                 " inner join [dbo].[Hasp_table] as has on has.CustomerID=cus.CustomerTag " & _
                                " inner join [dbo].[salesorder_table] as sal On sal.Hasp_ID =has.Hasp_ID Where cus.CustomerTag = '" & CboCustomers.SelectedValue.ToString & "'"
        Dim dap As SqlDataAdapter = New SqlDataAdapter(Sql, FormConnection)
        dap.Fill(dset, "dbo.Customer_Table")
        DGCustomer.DataSource = dset.Tables("dbo.Customer_Table")
    Else
        Dim erm As String = "wtf"
    End If

编辑:我发现这与我使用的发布配置设置有关,我猜它的优化位。有谁知道 vs 的任何实用程序/插件是否显示一条线是否已被优化。 delphi,我以前的语言在左边距显示蓝点表示它是一个编译行,没有点表示它没有编译,vs有没有类似的东西?

或者,有人可以解释优化如何影响这个简单的 if 语句,使其同时运行吗?

EDIT2:使用此线程作为可能的原因/解决方案:Bug only occurring when compile optimization enabled。 对于 x86、x64 和 AnyCPU 上的 release = 优化也是如此 关闭优化。 我在 x64 win7 机器上使用 V2005,如果这很重要的话。

EDIT3:继Chris 注释后,if 语句反编译为

If ((Not Me.CboCustomers.SelectedValue Is Nothing) And (Not Me.CboCustomers.SelectedValue Is "")) Then

所以我现在比以前更加困惑,因为这对我来说看起来很合理......

Edit4:erm 不是一个答案,而是它的作品,所以我现在宣布胜利并继续前进。如果有人知道不留下这个空的try catch的理由,请告诉我。或者如果有人能告诉我为什么 if 语句没有按预期工作,优化开启更好。

    Try
        If ((Not Me.CboCustomers.SelectedValue Is Nothing) And (Not Me.CboCustomers.SelectedValue Is "")) Then
            Dim Sql As String = "Select sal.SalesOrderNo As SalesOrder,cus.CustomerName,has.SerialNo, convert(varchar,sal.Dateofpurchase,103) as Date from [dbo].[Customer_Table] as cus " & _
                                     " inner join [dbo].[Hasp_table] as has on has.CustomerID=cus.CustomerTag " & _
                                    " inner join [dbo].[salesorder_table] as sal On sal.Hasp_ID =has.Hasp_ID Where cus.CustomerTag = '" & CboCustomers.SelectedValue.ToString & "'"
            Dim dap As SqlDataAdapter = New SqlDataAdapter(Sql, FormConnection)
            dap.Fill(dset, "dbo.Customer_Table")
            DGCustomer.DataSource = dset.Tables("dbo.Customer_Table")
        Else
            CboCustomers.SelectedIndex = 0
        End If
    Catch ex As Exception
        ' CODE REVIEW NOTE: MJR 16/06/2010
        '   1) This is very odd, i cant figure this out but this hack works.
        '   2) The try catch is here purely to make the if statement work as expected?!?!? 
        '   3) Take it out and both blocks of the if then else will execute in release mode, 
        '   at first i though "DGCustomer.DataSource = dset.Tables("dbo.Customer_Table")" raised an exception but ex is nothing.
        '   4) Ideas anyone?
    End Try

我投票赞成克里斯,因为他链接的反编译器工具比我拥有的免费工具和它的好建议要好。也赞成 Ho1,因为建议很简单,在走远之前重新启动 IDE 总是一个好主意,但我暂时忘记了。

感谢大家的宝贵时间和建议,如果您确实弄清楚了真正的原因,请务必发表解释

干杯

【问题讨论】:

  • 那么,你的意思是代码执行both执行数据绑定的块,以及分配字符串变量的Else块?
  • 是的,两者都执行。显然 else 块只是我输入的一段代码,试图弄清楚发生了什么,但是是的,双方!?>!?
  • 毫无疑问,我们必须解决错误,但这不是我可以忍受的。我在答案中添加了更精细和更多的诊断代码,以帮助追踪错误。我期待找出导致问题的原因。

标签: vb.net


【解决方案1】:

为了确保它不会被多次调用,添加一些 Diagnostics.Debug.WriteLine 语句

  1. if 之前的一个
  2. if 中的一个
  3. else里面的一个
  4. if 结束后一个

将这 4 个放在一起可以为您提供一个很好的时间表,了解它们是如何被调用的。

我遇到过一些实例(虽然很少而且相差甚远),实际上我必须重新启动机器才能使 Visual Studio 正常运行。

【讨论】:

  • 我现在试试,希望重启工作室能解决它,但它没有。
  • 重启机器没有解决。但是,调试配置不会以这种方式运行(它工作正常),所以这一定与我使用的发布配置有关。接下来我会调查。
【解决方案2】:

这不是一个真正的答案,但显然我没有代表发表评论。它只是一个调试建议......

我想到的一个想法是获取已编译的代码并使用 http://www.red-gate.com/products/reflector/ 之类的东西对其进行反编译。这应该会向您展示编译后 if 语句的样子。

【讨论】:

    【解决方案3】:

    只有调试的时候才有问题吗?如果您从命令行运行它,问题是否会消失。如果是这样,请删除包含您的调试信息的解决方案 suo 文件。此信息和文件可能已损坏。我也遇到过同样的问题。

    【讨论】:

    • 不,这仅在发布中发生,并且仅在优化开启时发生。
    【解决方案4】:

    我无法解释您遇到问题的原因。如果我正确理解了您的这部分问题:

    但是,如果我明确设置 条件为 1=0 或 1=1 然后 if 然后语句像我一样运行 预计。即只执行一侧 等式的...

    你所做的是:

    Dim dset As DataSet = New DataSet
    If 1 = 1 Then
        Dim Sql As String = "Select sal.SalesOrderNo As SalesOrder,cus.CustomerName,has.SerialNo, convert(varchar,sal.Dateofpurchase,103) as Date from [dbo].[Customer_Table] as cus " & _
                                 " inner join [dbo].[Hasp_table] as has on has.CustomerID=cus.CustomerTag " & _
                                " inner join [dbo].[salesorder_table] as sal On sal.Hasp_ID =has.Hasp_ID Where cus.CustomerTag = '" & CboCustomers.SelectedValue.ToString & "'"
        Dim dap As SqlDataAdapter = New SqlDataAdapter(Sql, FormConnection)
        dap.Fill(dset, "dbo.Customer_Table")
        DGCustomer.DataSource = dset.Tables("dbo.Customer_Table")
    Else
        Dim erm As String = "wtf"
    End If
    

    并且代码按预期工作。我的建议是按以下方式重构 If 语句:

    If Me.CustomerHasBeenSelected() Then
        Dim erm As String = "it worked!"
    Else
        Dim erm As String = "wtf"
    End If
    
    Private Function CustomerHasBeenSelected() As Boolean
        Return (CboCustomers.SelectedValue IsNot Nothing) AndAlso (CboCustomers.SelectedValue <> "")
    End Function
    

    希望这会有所帮助。

    PS。如果还是不能解决问题,可以进一步协助调试。

    Dim selected As Boolean = Me.CustomerHasBeenSelected()
    
    If selected Then
        Dim erm As String = "it worked!"
    Else
        Dim erm As String = "wtf"
    End If
    

    编辑 1

    截至 2010 年 6 月 17 日,Matma 仍然遇到最初的问题,并且有一个技巧,可以在问题周围添加 Try ... End Try 块。不是我能忍受的。我将采取的下一步是分解 if 语句,特别是 CustomerHasBeenSelected 方法,甚至进一步用于调试目的。这就是我现在编写代码的方式。

    Dim selected As Boolean = Me.CustomerHasBeenSelected()
    Dim crazyBug As Integer = 0
    
    If selected Then
    
        crazyBug += 1
    
        ... the real code ...
    
    Else
    
        crazyBug += 1
    
        ... the real code ...
    
    End If
    
    If crazyBug = 0 Then
        Throw New Exception("Neither side of the If statement ran.")
    ElseIf crazyBug > 1 Then
        Throw New Exception("Both sides of the If statement ran.")
    End If
    
    Private Function CustomerHasBeenSelected() As Boolean
    
        ' There is a crazy bug with the if statement that calls this method so
        ' using multiple if statements to help tracked down the problem.
    
        If (CboCustomers.SelectedValue Is Nothing)
            Return False
        End If
    
        If (CboCustomers.SelectedValue <> "")
            Return True
        End If
    
        Return False
    
    End Function
    

    【讨论】:

    • 是的,1=1 的假设是正确的,我也尝试过创建一个函数并使用结果方法,最后创建一个单独的布尔值并使用该方法。坦率地说,令人惊讶的是,这三个都给出了相同的结果,if 语句的两边都被执行了。然而,我刚刚找到了一种让它按预期执行的方法,我即将发布解决方案和一些额外的信息,以供其他任何人遇到类似奇怪的问题。购买是的,谢谢您的回复。
    猜你喜欢
    • 2016-02-09
    • 1970-01-01
    • 2015-08-13
    • 2014-03-04
    • 1970-01-01
    • 2010-09-07
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多