当引用的每个控件都必须存在并且具有 Text 属性时,为什么我会获得 NRE

本文关键字:属性 Text 为什么 NRE 引用 控件 存在 | 更新日期: 2023-09-27 18:35:06

我正在尝试通过为表单上的所有必需值提供特定的标签值来检查它们是否都有一个条目:

//HHSConsts.cs
public static int REQUIRED_FIELD = 1;
// FrmDelivery 
public FrmDelivery(NewDelivery newDel)
{
    InitializeComponent();
    . . .
    SetRequiredControls();
}
private void SetRequiredControls()
{
    // Required controls will have a Tag value of "1"
    textBoxCost.Tag = HHSConsts.REQUIRED_FIELD; 
    . . .

然后,当用户捣碎"保存"按钮时,将执行健全性检查:

private void buttonSave_Click(object sender, EventArgs args)
{
    if (RequiredDataMissing())
    {
        . . .
private bool RequiredDataMissing()
{
    return this.Controls.Cast<Control>().Any(ctrl => (ctrl.Tag.Equals(HHSConsts.REQUIRED_FIELD)) && (ctrl.Text.Equals(String.Empty)));
}

根据我的灯光,这是在说,"如果任何控件的标签为 1(是必需的)但为空,则返回 false。但是,它没有这样做(beningly返回布尔值),而是与 NRE 一起崩溃。更具体地说:

从应用程序范围的异常处理程序:System.NullReferenceException: NullReferenceException 在HHS。FrmDelivery.b__0(控制控制) at System.Linq.Enumerable.Any[TSource](IEnumerable 1 source, Func 2 谓词) 在HHS。FrmDelivery.RequiredDataMissing() 在HHS。FrmDelivery.buttonSave_Click(对象发送器,事件参数) . . .

为什么会这样;我必须取消我的花哨裤子RequiredDataMissing()代码的优雅,以使其按预期工作吗?

当引用的每个控件都必须存在并且具有 Text 属性时,为什么我会获得 NRE

我想您的表单包含其他未设置Tag(null)的控件,因此例外。

如果是这样,则需要修改 linq 查询:

return this.Controls.Cast<Control>().Any(ctrl => 
    ctrl.Tag != null 
    && ctrl.Tag.Equals(HHSConsts.REQUIRED_FIELD) 
    && ctrl.Text.Equals(String.Empty));

假设您没有在每个控件上设置 Tag 属性,您还需要检查Tag是否有可能的null值:

return this.Controls.Cast<Control>()
                    .Any(ctrl => (ctrl.Tag != null)
                              && (ctrl.Tag.Equals(HHSConsts.REQUIRED_FIELD))
                              && (ctrl.Text.Equals(String.Empty)));

或者,如果仅在单一类型的控件(如 TextBoxes)上设置Tag,请将检查限制为仅这些控件:

return this.Controls.OfType<TextBox>()
                    .Any(ctrl => (ctrl.Tag.Equals(HHSConsts.REQUIRED_FIELD))
                              && (ctrl.Text.Equals(String.Empty)));

您正在对标记调用.Equals,对于任何不需要的控件,该标记可能为 null。

举个简单的例子:

object o = null;  // Tags are objects
var areEqual = o.Equals(null);  // NRE