为什么这个对象引用应该不设置为一个显然已被编译器识别的对象的实例?

Why is this object reference supposedly not set to an instance of an object that has obviously been identified by the compiler?

有些人——也许是容易上当受骗——相信有多种方法可以成为猫皮匠。

当我尝试在页面上的所有控件中搜索复选框时,继续可耻地失败(有关证明,请参阅 ),我想也许我可以只查看控件的 ID,而不是关心它的核心是什么类型的控制。

所以,我注释掉了这一行:

If TypeOf cntrl Is System.Web.UI.WebControls.CheckBox Then

...并尝试这样做:

If cntrl.ID.ToString().Contains("ckbx")

但我也好不到哪里去,挨了一记冷水耳光:

Server Error in '/EMS/customerreportingnet' Application.
--------------------------------------------------------------------------------

Object reference not set to an instance of an object. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error: 

Line 69:             LabelDebug.Text = LabelDebug.Text+" "+cntrl.GetType().ToString+" "
Line 70:             'If TypeOf cntrl Is System.Web.UI.WebControls.CheckBox Then
Line 71:             If cntrl.ID.ToString().Contains("ckbx")
Line 72:             'Dim objAsConvertible As IConvertible = TryCast(cntrl, IConvertible)
Line 73:             'If objAsConvertible Is Nothing Then 

Source File: C:\EnhancedMonthlySalesReporting\customerreportingnet\customerreportingnet\pages\custmaint_categoryadmin.aspx.vb    Line: 71 

Stack Trace: 

[NullReferenceException: Object reference not set to an instance of an object.]
   pages_custmaint_categoryadmin.Button1_Click(Object sender, EventArgs e) in C:\EnhancedMonthlySalesReporting\customerreportingnet\customerreportingnet\pages\custmaint_categoryadmin.aspx.vb:71
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +114
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +139
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +28
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2980

--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:2.0.50727.5485; ASP.NET Version:2.0.50727.5491

为什么明明存在的控件,却像没有引用一样抛出异常?

整个代码块是:

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

For Each cntrl As Control In Me.Controls
    'If TypeOf cntrl Is System.Web.UI.WebControls.CheckBox Then
    If cntrl.ID.ToString().Contains("ckbx")
        If DirectCast(cntrl, CheckBox).Checked = True Then
            Label2.Text = "label 2 text from checked"
            curCheckboxIDVal = CStr(DirectCast(cntrl, CheckBox).ID)
            coName = GetLabelTextForID(curCheckboxIDVal)
            argVals = GetArgValsForCompanyName(coName)
            _Unit = argVals(0)
            _MemberNo = argVals(1)
            _CustNo = argVals(2)
            Label2.Text = _Unit
            LabelDebug.Text = _MemberNo
            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("@CustNo", SqlDbType.VarChar, 50).Value = _CustNo
                conn.Open()
                cmd.ExecuteScalar()
            End Using
        End If
    End If
Next

要到达引发错误的行,cntrl 必须 是Me.Controls 集合中的有效控件;我估计所有控件都有一个 ID 属性。因此,为什么在该行上抛出错误对我来说几乎没有意义。

问题出在这里:

If cntrl.ID.ToString().Contains("ckbx")  

cntrl.ID 似乎为空。 尝试调试以查看 cntrl.ID.ToString()

中的值

检查值是否为空:

If String.IsNullOrEmpty(cntrl.ID) then exit For

 If cntrl.ID Is Nothing Then exit For

事后看来,修复最终很简单,甚至合乎逻辑。

控件被动态添加到表单中,如下所示:

formCustCatMaint.Controls.Add(同名) 因此,在循环中替换这一行:

对于 Me.Controls 中的每个 cntrl 作为控件 ...用这个:

对于 formCustCatMaint.Controls 中的每个 cntrl 作为控件 而这一行,在 GetLabelTextForID() 函数中:

对于 Me.Controls 中的每个 cntrl 作为控件 ...用这个:

对于 formCustCatMaint.Controls 中的每个 cntrl 作为控件 ...成功了。正在找到控件,并且代码按 designed/originally 预期的方式工作。

Nebenbei bemerkt,现在也可以正常工作了:

If TypeOf cntrl Is CheckBox Then