对象引用未设置为实例,但不为null
本文关键字:null 实例 设置 对象引用 | 更新日期: 2023-09-27 18:27:25
我的流程中出现了一些意外行为。我正在做以下事情。
IEnumerable<Thing> things = ...;
IEnumerable<Thing> subset = things.Where(a => a.SomeFlag);
String info = "null: " + (subset == null);
上面的工作和信息告诉我对象不是空。所以我想通过这个来检查子集中元素的数量。
IEnumerable<Thing> things = ...;
IEnumerable<Thing> subset = things.Where(a => a.SomeFlag);
String info = "null: " + (subset == null);
String count = subset.Count();
现在我得到一个异常,给我错误消息:
对象引用未设置为对象的实例。
我想念什么?!
subset
中的一个Thing
可能是null
。你可以试试这个:
IEnumerable<Thing> subset = things.Where(a => a != null && a.SomeFlag);
请注意,由于Linq的惰性求值方式,您不会得到任何称为.Where
的异常,因为它在这一点上所做的只是设置一个过滤things
元素的条件。只有当您稍后调用.Count
时,它才真正评估结果。
更新:使用C#中新的null条件运算符(也称为安全导航或"Elvis"运算符),我们可以更简洁地做同样的事情:
IEnumerable<Thing> subset = things.Where(a => a?.SomeFlag);
IEnumerable<Thing>
表示延迟执行。
在您的第一个片段中,subset
和things
从未被枚举。
在第二个片段中,是对Count()
的调用枚举了这些列表,直到这时才发现其中一个a
在a => a.SomeFlag
中为空。
您可以通过一个稍微简化的示例看到这里真正发生了什么。
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
不会导致集合枚举,所以不会在任何source
集合元素上激发Where
谓词。
但是,当您在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的副作用,则仍然可以获得NullReferencesException。