2013-07-26 19 views
1

這是一個LINQ表達式的提取物:的NullReferenceException使用具有值類型Group.FirstOrDefault時

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() 

似乎當x.VatRate0FirstOrDefault拋出異常:

NullReferenceException

我可以通過將其更換爲:

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

它確保每次都有異常。

  • 爲什麼拋出空引用異常(這是一個值類型,因此沒有引用)?
  • 我該如何處理x.VatRate實際上是0的情況?
+0

@Skippy - 意思不相關 –

+0

我沒有做任何劃分,因爲你似乎認爲 –

+0

在這種情況下,它只是一個數字 –

回答

3

你錯誤地理解了VB.NET的類型強制的錯誤。

Group.FirstOrDefault(功能(x)的x.VatRate).VatRate

FirstOrDefault返回第一值匹配謂詞函數,或者如果沒有匹配的T默認值。由於您的功能不會評估爲truefalse,因此VB.NET會將int強制爲bool。在這種情況下,0 is converted to false and any other value is converted to true

因此,當x.VatRate不是0時,則第一個IndividualCharge將通過謂詞過濾器。當VatRate0時,則不會有IndividualCharge通過謂詞過濾器,並返回null(默認值爲IndividualCharge)。試圖抓住VatRate然後導致您的NullReferenceException

大概,你真的想要第一個VatRate,不管它是不是0。將您的代碼更改爲:

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

應該完成該操作。

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() 
0

這是由VB隱式強制引起的。 FirstOrDefault方法需要一個返回Boolean的函數。您正在傳遞一個返回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如果有,或否則爲零。

相關問題