为什么此 "Is" 测试在此比较中失败?

Why does this "Is" test fail with this comparison?

我有这个代码来比较两个控制标签值的值:

Protected Function GetLabelTextForTag(tagVal As String) As String
    Dim CoName As String = ""
    For Each cntrl As Control In Me.Controls
        If TypeOf cntrl Is Label Then
            If DirectCast(cntrl, Label).Tag Is tagVal Then
                CoName = DirectCast(cntrl, Label).Text
                Exit For
            End If
        End If
    Next
    Return CoName
End Function

虽然我到了这一行,但是:

If DirectCast(cntrl, Label).Tag Is tagVal Then

...并且 Tag 与 tagVal("1") 相同,未到达下一行 - "1" 不被视为与 "1" 相同的东西"

不熟悉 VB,我想也许 "Is" 是问题所在。但是,我一开始使用 "IS" 的原因是,当我第一次尝试这个时:

If DirectCast(cntrl, Label).Tag = tagVal Then

...我得到,“错误 1 ​​Option Strict On 不允许运算符“=”的对象类型的操作数。使用 'Is' 运算符来测试对象标识。"

该函数由按钮单击的事件处理程序调用:

Private Sub Button1_Click( sender As Object,  e As EventArgs) Handles Button1.Click
        Dim connStr As String = "SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=durante;PWD=pondscum"
        Dim upd8DML As String = "UPDATE CustomerCategoryLog SET Category = 'Exploding' WHERE Unit = @Unit And MemberNo = @MemberNo AND Custno = @CustNo"

        Dim coName As String
        Dim argVals(2) As String
        Dim _Unit As String
        Dim _MemberNo As String
        Dim _CustNo As String
        Dim curTagVal As String

        For Each cntrl As Control In Me.Controls
            If TypeOf cntrl Is CheckBox Then
                If DirectCast(cntrl, CheckBox).Checked = True Then
                    curTagVal = CStr(DirectCast(cntrl, CheckBox).Tag)
                    coName = GetLabelTextForTag(curTagVal)
                    argVals = GetArgValsForCompanyName(coName)
                    _Unit = argVals(0)
                    _MemberNo = argVals(1)
                    _CustNo = argVals(2)
                    Using conn As New SqlConnection(connStr), _
                        cmd As New SqlCommand(upd8DML, conn)
                        cmd.Parameters.Add("@CoName", SqlDbType.VarChar, 50).Value = coName
                        conn.Open
                        cmd.ExecuteScalar()
                    End Using
                End If
            End If
        Next
End Sub

我正在寻找具有相同标记值的标签和复选框,因为我动态地创建了一些这些控件对,并且需要知道针对哪些标签选中了哪些对应的复选框。我像这样创建它们(一些,这只是一个测试):

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim sqlConnection1 As New SqlConnection("SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=durante;PWD=pondscum")
        Dim cmd As New SqlCommand
        Dim reader As SqlDataReader

        cmd.CommandText = "select C.CompanyName from CustomerCategoryLog CCL join Customers C on C.CustNo = CCL.Custno where CCL.Category = 'New' and C.Active <> 0 order by C.CompanyName"
        cmd.CommandType = CommandType.Text
        cmd.Connection = sqlConnection1

        sqlConnection1.Open()

        reader = cmd.ExecuteReader()
        ' Data is accessible through the DataReader object here.
        If reader.HasRows Then
            Dim i As Integer = 0

            While reader.Read()
                i = i+1
                If i > 12 'There are thousands...just grab the first dozen for this test
                    Exit While
                End If

                Dim lblCompanyName = New Label()
                lblCompanyName.Tag = i.ToString() 'ID not available...?!?
                lblCompanyName.Text = reader.Item(0).ToString()
                Me.Controls.Add(lblCompanyName)

                Dim ckbx = New CheckBox()
                ckbx.Tag = i.ToString()
                ckbx.Checked = True
                Me.Controls.Add(ckbx)
            End While
        End If
        reader.Close()

        sqlConnection1.Close()
    End Sub

为了更好的衡量,我也可以在表单上添加唯一的其他代码:

Protected Function GetArgValsForCompanyName(coName As String) As String()
        Dim args(2) As String
        Dim sqlConnection1 As New SqlConnection("SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=durante;PWD=pondscum")
        Dim cmd As New SqlCommand
        Dim reader As SqlDataReader

        cmd.CommandText = "select Unit, MemberNo, CustNo from Customers WHERE CompanyName = @CoName"
        cmd.CommandType = CommandType.Text
        cmd.Parameters.Add("@CoName", SqlDbType.VarChar, 50).Value = coName
        cmd.Connection = sqlConnection1
        sqlConnection1.Open()

        reader = cmd.ExecuteReader()
        ' Data is accessible through the DataReader object here.
        If reader.HasRows Then
                args(0) = reader.Item(0).ToString()
                args(1) = reader.Item(1).ToString()
                args(2) = reader.Item(2).ToString()
        End If
        reader.Close()
        sqlConnection1.Close()

        Return args
    End Function

什么时候“1”不是“1”?

好的,Tag 是一个对象而不是字符串,因此使用 strict 选项你会遇到问题,试试

If DirectCast(cntrl, Label).Tag.ToString() = tagVal Then

使用 Is 你比较的是引用而不是值。

也为您解决了这个问题

    Private Sub Button1_Click( sender As Object,  e As EventArgs) Handles Button1.Click
            Dim connStr As String = "SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=durante;PWD=pondscum"
            Dim upd8DML As String = "UPDATE CustomerCategoryLog SET Category = 'Exploding' WHERE Unit = @Unit And MemberNo = @MemberNo AND Custno = @CustNo"

            Dim coName As String
            Dim argVals(2) As String
            Dim _Unit As String
            Dim _MemberNo As String
            Dim _CustNo As String
            Dim curTagVal As String

            For Each cntrl As Control In Me.Controls
                If TypeOf cntrl Is CheckBox Then
                    If DirectCast(cntrl, CheckBox).Checked = True Then
                        curTagVal = CStr(DirectCast(cntrl, CheckBox).Tag)
                        coName = GetLabelTextForTag(curTagVal)
                        argVals = GetArgValsForCompanyName(coName)
                        _Unit = argVals(0)
                        _MemberNo = argVals(1)
                        _CustNo = argVals(2)
                        Using conn As New SqlConnection(connStr), _
                            cmd As New SqlCommand(upd8DML, conn)
                            cmd.Parameters.Add("@Unit", SqlDbType.VarChar, 50).Value = _Unit
                            cmd.Parameters.Add("@MemberNo", SqlDbType.VarChar, 50).Value = _MemberNo
                            cmd.Parameters.Add("@CoName", SqlDbType.VarChar, 50).Value = coName
                            conn.Open
                            cmd.ExecuteScalar()
                        End Using
                    End If
                End If
            Next

End Sub

我仍然不知道为什么原始代码不起作用,但将其更改为以下代码:

Protected Function GetLabelTextForTag(tagVal As String) As String
    Dim CoName As String = ""
    Dim lblTag As String
    For Each cntrl As Control In Me.Controls
        If TypeOf cntrl Is Label Then
            lblTag = CStr(DirectCast(cntrl, Label).Tag)
            If lblTag = tagVal Then
                CoName = DirectCast(cntrl, Label).Text
                Exit For
            End If
        End If
    Next
    Return CoName
End Function