【问题标题】:Proper null check正确的空检查
【发布时间】:2016-07-02 12:04:54
【问题描述】:

我正在实例化一个 Associate 对象,并从我的主窗体内的 txtboxes 为其分配属性。空值检查的最佳做法是什么?是在分配之前使用 if 语句检查每个属性还是有更好的方法?这是我的代码:

Associate updateAssociate = new Associate();

updateAssociate.AssocID = txtAssocId.Text;
updateAssociate.FirstName = txtFname.Text;
updateAssociate.LastName = txtLname.Text;
updateAssociate.HireDate = Convert.ToDateTime(txtHireDate.Text);
updateAssociate.ContractEndDate = Convert.ToDateTime(txtContractEnd.Text);
updateAssociate.TerminationDate = Convert.ToDateTime(txtTerminationDate.Text);
updateAssociate.FullPartTimeID = cboFullPart.SelectedText;
updateAssociate.PrimaryRole = cboPRole.SelectedText;

【问题讨论】:

  • 您究竟期望什么为空?所有控件将始终存在,除非您将代码放在错误的位置开始。 (或者自己动态创建控件?)
  • 我希望您在 UI 上进行某种验证,除非填充了必填字段,否则您不允许用户创建和 Associate。余数应为string.Empty
  • 对不起,要清除控件的内容。如果它是一个文本框,那么它将是 .Text 属性,我想在将它们分配给对象之前检查空值或空白值。
  • @VinnyGuitara:目前还不清楚您要解决的实际问题是什么。除非有其他问题,否则发布的代码中似乎没有很高的空引用概率。对于分配的任何给定属性,如果值为 null,您还想做什么?
  • @David.... 所以如果我的表单是从数据库中填充的,然后我会从我试图处理的文本字段中实例化一个 Associate 对象,如果这些字段之一从DB 为空。

标签: c# oop properties null


【解决方案1】:

根据您对问题的评论:

如果它是一个文本框,那么它将是 .Text 属性,我想在将它们分配给对象之前检查空值或空白值

您可以在分配时使用空值合并运算符来检查空值:

updateAssociate.AssocID = txtAssocId.Text ?? string.Empty;

或:

updateAssociate.AssocID = txtAssocId.Text ?? someDefaultValue;

这样,如果txtAssocId.Textnull,那么您将定义的默认值分配给对象属性而不是null

虽然我不完全确定TextBox.Text 属性会成为 null 而不是空字符串。也许您想同时检查两者?:

updateAssociate.AssocID = string.IsNullOrEmpty(txtAssocId.Text) ? someDefaultValue : txtAssocId.Text;

【讨论】:

  • 我认为这就是答案,那么组合框值属性呢。如果组合框为空,则 value 属性将为空,对吗?如果是这样,我将如何处理?我有这个:updateAssociate.Location = (cboLocation.SelectedValue ?? string.Empty).ToString();
  • @VinnyGuitara:对于任何给定的控件,它肯定可能会略有不同,尤其是对于类型为objectComboBox.SelectedValue。但总体原理是一样的。无论您想在逻辑中检查null 或其他一些不需要的值,您只需检查它。可以像空合并运算符(或 C#6+ 中的空条件运算符)一样简单,也可以像多行 if 块一样复杂。无论哪种方式,条件操作都是条件操作。
  • 我想尝试使用空合并,因为它看起来更干净。有没有办法在对象类型上使用它?
  • @VinnyGuitara:您可能遇到的唯一限制是必须在编译时确定操作的结果类型。因此,诸如空合并运算符或三元条件运算符之类的内联条件需要在其自身中“宣传”单个可能的结果类型。你有没有这样的例子吗?
  • 我现在有这样的东西:updateAssociate.FullPartTimeID = cboFullPart.SelectedText ??字符串。空; updateAssociate.PrimaryRole = cboPRole.SelectedText ??字符串。空; updateAssociate.SystemDomain = cboDomain.SelectedText ??字符串。空; if (txtTerminationDate.Text != null || txtTerminationDate.Text != string.Empty) updateAssociate.TerminationDate = Convert.ToDateTime(txtTerminationDate.Text ?? string.Empty);
【解决方案2】:

在 C# 6 中,它将是 null-conditional operator

updateAssociate.AssocID = txtAssocId?.Text;

在以前的 c# 版本中,您可以编写一个方法来消除代码重复。像这样的:

public static T CheckNull<T>(Func<T> canBeNull) where T : class
    {
        try
        {
            return canBeNull();
        }
        catch (NullReferenceException)
        {
            return default(T);
        }
    }

并像这样使用它

updateAssociate.AssocID = CheckNull(() => txtAssocId.Text);

然后你可以将任何可以抛出空引用的代码包装到 lambda 中,将它传递给这个方法,而不再为它烦恼。

【讨论】:

  • 这看起来很有趣。我将如何在上面的代码中实现这一点?
  • return item == null ? default(T) : item; 等于return item; 因为default(T) == nullT
  • @Dmitry 也许吧。该解决方案是模仿空条件运算符。你不需要重写代码,只需将它包装成 lambda 就可以了。
  • 这确实应该有两种泛型。如果你想模仿?.,输入(?. 之前的项目)和输出(?. 之后的项目)。
  • @jugarr 为什么需要?. 之前的类型?它必须是引用类型,这才是最重要的。
猜你喜欢
  • 1970-01-01
  • 2015-05-21
  • 1970-01-01
  • 2017-12-09
  • 2012-04-05
  • 1970-01-01
  • 2017-10-04
  • 2016-05-10
  • 1970-01-01
相关资源
最近更新 更多