1

这是 linq 表达式的摘录:

Dim charges As List(Of IndividualCharge) = (From t In totals
                    Group t By t.InvId
                    Into Group
                    Select New IndividualCharge With {
                    .VatRate = Group.FirstOrDefault(Function(x) x.VatRate).VatRate
                    }).ToList()

似乎 when x.VatRateis 0FirstOrDefault引发异常:

空引用异常

我可以通过将其换成以下内容来确认这一点:

.VatRate = Group.FirstOrDefault(Function(x) 0).VatRate

确保每次都出现异常。

  • 为什么会抛出空引用异常(这是一种值类型,因此没有引用)?
  • 我该如何处理 x.VatRate 实际上是的情况0
4

3 回答 3

3

您误读了错误,并且由于 VB.NET 的类型强制而更加复杂。

Group.FirstOrDefault(Function(x) x.VatRate).VatRate

FirstOrDefault返回与谓词函数匹配的第一个值,或者T如果没有匹配项则返回默认值。由于您的函数不会评估为trueor false,因此 VB.NET 将强制int转换为bool. 在这种情况下,0被转换为false并且任何其他值都被转换为true

因此,当x.VatRateis not时0,第一个IndividualCharge通过谓词过滤器。当VatRateis时0,则 noIndividualCharge通过谓词过滤器并返回null(的默认值IndividualCharge)。试图VatRate在你的NullReferenceException.

大概,你真的想要第一个VatRate,不管它是否为 0。将您的代码更改为:

Group.Select(Function(x) x.VatRate).First()

应该做到这一点。

于 2013-07-26T15:01:03.550 回答
0

当您将表达式传递给 FirstOrDefault 时,您告诉它选择与表达式匹配的第一个项目(很像 Where 子句,但要匹配该子句的第一个对象)。如果您将您的陈述更改为以下内容,可以吗?

Dim charges As List(Of IndividualCharge) = (From t In totals
                    Group t By t.InvId
                    Into Group
                    Select New IndividualCharge With {
                    .VatRate = Group.FirstOrDefault().VatRate
                    }).ToList()

如果您想获得第一个不为零的值,那么沿着这些线应该做什么?

Dim charges As List(Of IndividualCharge) = (From t In totals
                    Group t By t.InvId
                    Into Group
                    Select New IndividualCharge With {
                    .VatRate = if(Group.Any(function(o) o.VatRate > 0),  Group.FirstOrDefault(function(o) o.VatRate > 0).VatRate, -1)
                    }).ToList()
于 2013-07-26T14:48:02.603 回答
0

这是由 VB 的隐式类型强制导致的。该FirstOrDefault方法需要一个返回 a 的函数Boolean。您正在传递一个返回 a 的函数Decimal,因此 VB 将其转换为:

Group.FirstOrDefault(Function(x) x.VatRate <> 0)

如果组中的所有项目都没有非零VatRate,这将返回Nothing。然后,您尝试访问VatRate返回对象的属性,这会导致NullReferenceException.

尝试使用:

Group.Where(Function(x) x.VatRate <> 0)
   .Select(Function(x) x.VatRate)
   .FirstOrDefault()

如果有一个,则应该返回第一个VatRate非零,否则返回零。

于 2013-07-26T15:00:41.193 回答