创建空列表时可能导致Null引用异常的原因

本文关键字:引用 Null 异常 列表 创建 | 更新日期: 2023-09-27 18:13:41

更新

这似乎是Visual Studio中跨接方法的问题,与Linq语句的内容没有直接关系。为了执行这段代码,我使用调试器跳过了一些耗时的方法——如果我不跳过它们,而是让它们在第一行返回,错误就会消失。

我有一个可重复的例子,下面的代码在最后一行抛出了一个空引用异常:

            List<Product> testList = new List<Product>
            {
                new Product
                {
                    Sku = "sku"
                }
            };
            string sku = testList.First().Sku;
            var simpleQuery = testList.Select(p => p.Sku);
            List<string> skus = simpleQuery.ToList();

但只有当我跳过调试器跳过一个方法时才会发生这种情况(即使我跳过的方法看起来像这样(:

    private bool DoSeomthing()
    {
        return false;
    }

我很想知道是否有人能重新制作这个,或者有任何想法可能导致它…

原件

在一段相对常规的代码中,我偶然发现了一些相当奇怪的行为,令人困惑,我不知道如何进一步调查。

似乎当我尝试实例化一个List,然后在多个LINQ查询中使用该列表时,初始实例化会抛出一个null引用异常。

此代码的第一行抛出"Object reference not set to a instance of a Object">

我已经注释掉了实际的存储库代码,但仅仅使用new List((仍然会抛出。

List<Product> testProducts = new List<Product>();
                               // _repo.Products().ToList();

List<Product> deleteProducts = 
    testProducts .Where(p => !(importProducts.Select(ip => ip.Sku).Contains(p.Sku))).ToList();
List<Product> addedProducts = //new List<Product>();
    importProducts.Where(p => !(testProducts.Select(ip => ip.Sku).Contains(p.Sku))).ToList();

如果我将addedProducts的声明更改为新的List,而不是linq查询,那么代码运行得很好。

怎么行:

List<Product> testProducts = new List<Product>();

抛出null引用异常?

可能是一些奇怪的编译器优化错误或其他什么?为什么会发生这种情况?可以做些什么来解决它?

我使用的是Visual Studio 2013,产品是实体框架6.0.0.0版本的对象。我试过重新启动Visual Studio,清理解决方案,重新启动机器,但没有什么乐趣。和往常一样,在这种奇怪的情况下,我相信上周也有同样的代码。。。

创建空列表时可能导致Null引用异常的原因

通常,当我对带有实体框架的NullReferenceException感到困惑时,我会发现这并不是因为我所做的返回null,而是因为我试图引用null的属性

例如,如果未找到任何项目,FirstOrDefault()将返回null,但是:

string Name = db.Items.FirstOrDefault(x => x.Id == 1).Name;

将抛出一个NulReferenceException,因为当从调用返回null时,它无法获取其Name属性。

我的建议是将嵌套调用拆分为单独的变量并传入,这样就可以隔离出哪个表达式实际返回了null。

另一件可能令人困惑的事情是EF的延迟执行——通常抛出错误的行是而不是导致错误的行,这只是碰巧执行错误语句的不幸行。

我遇到了类似的问题,这是我的代码:

if (true)
{
    List<Product> addedProducts;
    addedProducts = new List<Product>();    // Works
}
else
{
    List<Product> addedProducts;
    addedProducts = new List<Product>();    // Throw Exception
}

解决方案是在方法开始时移动声明:

List<Product> addedProducts;
if (true)
    addedProducts = new List<Product>();    // Works
else
    addedProducts = new List<Product>();    // Works

编译器允许您在同一方法的不同作用域中声明两个具有相同名称的变量,但当您尝试在else中初始化时,会得到NullReferenceException

您还可以查看生成的IL(并将其包含在您的问题中(。

如果我将addedProducts的声明更改为新的List,而不是一个linq查询,那么代码运行得很好。

那么这个错误很可能就在这个语句中。

检查此语句中的所有对象,并确保它们已实例化。您确定anotherTestProducts不为空吗?

有时,当抛出错误时,lne VS突出显示的内容可能会产生误导。