簡體   English   中英

對象引用未設置為實例而不為空

[英]Object reference not set to an instance while not being null

我在我的過程中遇到了一些意想不到的行為。 我正在做以下事情。

IEnumerable<Thing> things = ...;
IEnumerable<Thing> subset = things.Where(a => a.SomeFlag);
String info = "null: " + (subset == null);

上面的工作和信息告訴我該對象不為null 所以我希望通過這個來檢查子集中元素的數量。

IEnumerable<Thing> things = ...;
IEnumerable<Thing> subset = things.Where(a => a.SomeFlag);
String info = "null: " + (subset == null);
String count = subset.Count();

現在我得到一個例外,給我錯誤信息:

你調用的對象是空的。

我錯過了什么?!

有可能其中一個Thingsubsetnull 你可以試試這個:

IEnumerable<Thing> subset = things.Where(a => a != null && a.SomeFlag);

請注意,由於Linq的懶惰評估方式,你不會得到你調用的任何異常.Where因為它在那時所做的只是設置過濾things元素的條件。 只有在你調用.Count才會實際評估結果。

更新:使用C#6中的新的null條件運算符 (也稱為安全導航或'Elvis'運算符),我們可以更簡潔地執行相同的操作:

IEnumerable<Thing> subset = things.Where(a => a?.SomeFlag);

IEnumerable<Thing>意味着延遲執行。

在您的第一個片段subsetthings永遠不會被枚舉。

在第二個片段中,對Count()的調用枚舉了列表,然后才發現a => a.SomeFlaga => a.SomeFlag中的a為null。

你可以通過一些簡化的例子看到這里真正發生的事情。

Test類:

public class Test
{
    public int Value { get; set; }
}

IEnumerable<Test>上的LINQ查詢:

IEnumerable<Test> source = new List<Test>() {
    new Test { Value = 10 },
    null,
    new Test { Value = 20 }
};

IEnumerable<Test> filteredSource = source.Where(x => x.Value > 10);

// return false
Console.WriteLine(filteredSource == null);

// throws NullReferenceException
Console.WriteLine(filteredSource.Count());

為什么會這樣? 由於filteredSource == null不會導致集合枚舉 ,所以Where謂語不被任何上觸發source集合元素。

但是,當您在filteredSource上調用Count() ,將對source集合中的每個項調用謂詞,並且當涉及到null的項時: null.Value > 10將拋出異常。

如何使它工作? 使用x != null檢查擴展謂詞:

IEnumerable<Test> filteredSource = source.Where(x => x != null && x.Value > 10);

好了,假設你有以下項目things

Thing A  SomeFlag = true
Thing B  SomeFlag = false
null
Thing C  SomeFlag = true

首先,你指望在所有項目things 所以你迭代4個對象,找到4個對象,並且知道結果是4.簡單。

現在,您想要計算subset所有項目,這意味着您需要首先確定哪些項目屬於subset 所以你要計算它們:

Thing A .... A.SomeFlag is true, so count it
Thing B .... B.SomeFlag is not true, so don't count it
null    .... null.SomeFlag  NULLREFERENCEEXCEPTION

這就是你的錯誤來自哪里。

請注意,即使事物中的所有元素都不為null,如果.SomeFlag get訪問器具有可能導致NullReferenceException的副作用,您仍然可以獲得NullReferenceException。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM