我的过程中出现了一些意想不到的行为。我正在做以下事情。
IEnumerable<Thing> things = ...;
IEnumerable<Thing> subset = things.Where(a => a.SomeFlag);
String info = "null: " + (subset == null);
上述作品和 info 告诉我该对象不是 null 。所以我希望通过这个来检查子集中的元素数量。
IEnumerable<Thing> things = ...;
IEnumerable<Thing> subset = things.Where(a => a.SomeFlag);
String info = "null: " + (subset == null);
String count = subset.Count();
现在我得到一个异常,给我错误信息:
对象引用未设置为对象的实例。
我想念什么?!
答案 0 :(得分:5)
Thing
中的subset
之一可能是null
。你可以试试这个:
IEnumerable<Thing> subset = things.Where(a => a != null && a.SomeFlag);
请注意,由于Linq的懒惰评估方式,您无法获得拨打.Where
的任何异常,因为此时所做的一切都是为此设置条件过滤things
的元素。只有在您致电.Count
之后才会实际评估结果。
更新:使用C#6中的新null-condition operator(也称为安全导航或&#39; Elvis&#39;运营商),我们可以做同样的事情简洁地:
IEnumerable<Thing> subset = things.Where(a => a?.SomeFlag);
答案 1 :(得分:5)
IEnumerable<Thing>
意味着延迟执行。
在您的第一个片段中,subset
和things
永远不会被枚举。
在第二个片段中,对Count()
的调用枚举了列表,然后才发现a
中的a => a.SomeFlag
之一为空。
答案 2 :(得分:3)
你可以通过一些简化的例子看到这里真正发生的事情。
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
谓词。
但是,当您在Count()
上致电filteredSource
时,系统会在source
集合中的每个项目上调用谓词,并且当涉及到null
的项目时: null.Value > 10
抛出异常。
如何让它发挥作用?使用x != null
检查扩展谓词:
IEnumerable<Test> filteredSource = source.Where(x => x != null && x.Value > 10);
答案 3 :(得分:2)
好的,假设您在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。