简体   繁体   English

对象引用未设置为实例而不为空

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

I'm getting some unexpected behavior in my process. 我在我的过程中遇到了一些意想不到的行为。 I'm doing the following. 我正在做以下事情。

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

The above works and info tells me that the object isn't null . 上面的工作和信息告诉我该对象不为null So I wish to check the number of the elements in subset by this. 所以我希望通过这个来检查子集中元素的数量。

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

Now I get an exception giving me the error message: 现在我得到一个例外,给我错误信息:

Object reference not set to an instance of an object. 你调用的对象是空的。

What do I miss?! 我错过了什么?!

It's possible that one of the Thing 's in subset is null . 有可能其中一个Thingsubsetnull You can try this: 你可以试试这个:

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

Note that due to the way Linq's lazy evaluation, you won't get any exception you call .Where because all it's doing at that point is setting up a condition for filtering the elements of things . 请注意,由于Linq的懒惰评估方式,你不会得到你调用的任何异常.Where因为它在那时所做的只是设置过滤things元素的条件。 Only later when you call .Count is it actually evaluating the results. 只有在你调用.Count才会实际评估结果。

Update: With the new null-condition operator in C# 6 (also called the safe navigation or 'Elvis' operator), we can do the same thing a bit more succinctly: 更新:使用C#6中的新的null条件运算符 (也称为安全导航或'Elvis'运算符),我们可以更简洁地执行相同的操作:

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

An IEnumerable<Thing> implies deferred execution. IEnumerable<Thing>意味着延迟执行。

In your first fragment subset and things are never enumerated. 在您的第一个片段subsetthings永远不会被枚举。

In the second fragment, it is the call to Count() that enumerates the lists and only then it comes to light that one of the a is null in a => a.SomeFlag . 在第二个片段中,对Count()的调用枚举了列表,然后才发现a => a.SomeFlaga => a.SomeFlag中的a为null。

You can see what really happens here with a bit simplified example. 你可以通过一些简化的例子看到这里真正发生的事情。

Test class: Test类:

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

And LINQ query on IEnumerable<Test> : 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());

Why does it happens? 为什么会这样? Because filteredSource == null does not cause collection enumeration , so Where predicate is not being fired on any source collection element. 由于filteredSource == null不会导致集合枚举 ,所以Where谓语不被任何上触发source集合元素。

However, when you call Count() on filteredSource the predicate is being called on every item from source collection, and when it comes to an item which is null : null.Value > 10 throws the exception. 但是,当您在filteredSource上调用Count() ,将对source集合中的每个项调用谓词,并且当涉及到null的项时: null.Value > 10将抛出异常。

How to make it work? 如何使它工作? Extend the predicate with x != null check: 使用x != null检查扩展谓词:

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

Ok, so suppose you had the following items in things : 好了,假设你有以下项目things

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

First you count all the items in things . 首先,你指望在所有项目things So you iterate over 4 objects, find 4 objects, and know that the result is 4. Easy. 所以你迭代4个对象,找到4个对象,并且知道结果是4.简单。

Now you want to count all of the items in subset which means you need to figure out which items are in subset in the first place. 现在,您想要计算subset所有项目,这意味着您需要首先确定哪些项目属于subset So you go about counting them: 所以你要计算它们:

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

And that's where your error comes from. 这就是你的错误来自哪里。

Note that even if all of the elements in things are not null, you can still get a NullReferenceException if the .SomeFlag get accessor has a side effect that could cause a NullReferenceException. 请注意,即使事物中的所有元素都不为null,如果.SomeFlag get访问器具有可能导致NullReferenceException的副作用,您仍然可以获得NullReferenceException。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 空引用:对象引用未设置为对象的实例 - Null Reference : Object reference not set to an instance of an object 对象引用未设置为检查null的对象实例 - object reference not set to an instance of an object in check for null 未将对象引用设置为对象的实例,null - Object reference not set to an instance of an object, null “对象引用未设置为对象的实例”-但是没有什么是空的? - “Object reference not set to an instance of an object” - but nothing is null? 对象引用未设置为对象的实例(null DataSet ??) - Object reference not set to an instance of an object (null DataSet??) 未将对象引用设置为对象的实例,参数为null - Object reference not set to an instance of an object, parameter is null 获取对象引用未设置为对象实例的空引用对象的类型 - Get type of null reference object for Object reference not set to an instance of an object 数据存储库实例Null-NullReferenceException吗? 你调用的对象是空的 - Data Repository instance Null - NullReferenceException? Object reference not set to an instance of an object 对象引用未设置为对象的实例-空引用异常 - Object reference not set to an instance of an object - Null Reference Exception 你调用的对象是空的。 与非null对象。 - Object reference not set to an instance of an object. with a non null object.
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM