首页 > 解决方案 > Lambda 检查对象数组上的空值 - ArgumentNullException

问题描述

我正在尝试BranchCodeUserBranches(). 对于特定用户,该列表什么都不是,因此会导致异常:

System.ArgumentNullException: '值不能为空。
参数名称:source'

我正在使用一个IIF语句,但显然没有帮助:

Dim sMatchedBranches = IIf(Not IsNothing(oUser.UserBranches),
                           oUser.UserBranches.Select(Function(z) String.Format("{0} - BranchCode", z.BranchCode)), "")

我也用过oUser.UserBranches.Any,但还是一样的例外。有任何想法吗?

** 对于重复的建议,实际上并不是因为问题结合了 IIF 和带有 lambda 表达式的空数组。

标签: vb.net

解决方案


首先,我要重申@TnTinMn 所说的:尝试摆脱 Microsoft.VisualBasic。选择那里有用的东西是可以的 - 在这种情况下要非常周到和有意(例如,即使是 C#'ers 也非常喜欢 InputBox! - VB.net 的 InputDialog 的 C# 版本是什么?)。然而,今天的 VB 有很多更好更好的方法来完成任务。

ye olde 的主要缺陷IIf()是它只是一些函数,这意味着无论条件如何,每个参数都会被执行。这使得它几乎没有用处,即使在 VB6/VBA 中也是如此,因为您无法避免任何您知道将根据条件发生的运行时错误/异常。If()另一方面,它是一个实际的运算符,它提供了每个人都想要的东西——一种在表达式中仔细修剪执行的内容而无需编写专门的函数的方法。

所以简单的答案就是替换IIf()If()并完成它:

Dim sMatchedBranches = If(Not IsNothing(oUser.UserBranches),
                       oUser.UserBranches.Select(Function(z) String.Format("{0} - BranchCode", z.BranchCode)), "")

人们可能会觉得这已经足够好了。但是 VB 中还有其他三个技巧可以让事情变得更好。

首先是?运营商。这是一种方便的表达方式,例如If(oUser.UserBranches Is Nothing, Nothing, oUser.UserBranches.Select(Function(z) String.Format("{0} - BranchCode", z.BranchCode))),除了?现在是这样的:

oUser.UserBranches?.Select(Function(z) String.Format("{0} - BranchCode", z.BranchCode))

第二个技巧是字符串插值,格式为$"{myVar}". 而不是String.Format("{0} - BranchCode", z.BranchCode),它现在可以是:

$"{z.BranchCode} - BranchCode"

第三个技巧是关于If():如果你给它两个参数,它会给出一个非常方便的处理方式NothingIf(x,y)表示如果x不是Nothing,则返回x,否则返回y。(与 C# 中If(x,y)的含义相同x ?? y。)

把它们放在一起:

Dim sMatchedBranches = If(oUser.UserBranches?.Select(Function(z) $"{z.BranchCode} - BranchCode"), "")

推荐阅读