【问题标题】:How can the input parameter of a LINQ to Objects expression be nullLINQ to Objects 表达式的输入参数如何为空
【发布时间】:2020-10-14 16:12:50
【问题描述】:

我有一个我试图用 LINQ 查询的对象集合。莫名其妙,查询特定值时代码崩溃了。

SomeObject[] myObjects = { ... };

foreach (int id in someIDs)
{
    SomeObject singleObject = myObjects.FirstOrDefault(x => x.ID = id);
}

id 的值为特定值时,此代码将失败。我得到的错误是x 是NULL。 myObjects 数组不是 NULL,并且包含一个对象,其 ID 值与失败的 id 值匹配。 id 的其他值不会导致错误。当 id 是失败的值时,我可以在 LINQ 表达式迭代数组中的项目时单步执行它。参数x 对集合中的每个项目都有一个值,直到它到达与id 有问题的值匹配的项目之前的项目;此时x突然变为NULL并抛出异常。

非 NULL 集合上的 LINQ 表达式的输入参数怎么可能是 NULL?即使集合不包含 ID 匹配 id 的项目,它也应该只返回我的对象​​类型的默认值,而不是由于 NULL 错误而崩溃。

【问题讨论】:

  • 并不是说myObjectsnull,而是说myObjects元素成员null。例如。 SomeObject[] myObjects = new[] { foo, bar, null, baz };.
  • x => x != null && x.ID = id
  • 另外,您发布的代码的运行时复杂性很差 (O( n * m ))。您应该首先将myObjects 转换为字典(在循环外),以便在循环内获得O(1) 查找和O( n ) 整体性能。
  • myObjects.FirstOrDefault(x => x?.ID == id);
  • @Dai,谢谢。我很困惑,因为该集合不应该包含任何空值。结果发现一个错误是在集合中插入空值。

标签: c# linq-to-objects


【解决方案1】:

修复空值大幅提高运行时性能,如下所示:

SomeObject[] myObjects = new[] { ... };

Dictionary<Int32,SomeObject> dict = myObjects
    .Where( mo => mo != null )
    .ToDictionary( mo => mo.id );

foreach( Int32 id in someIds )
{
    if( dict.TryGetValue( id, out SomeObject singleObject ) )
    {
        // do stuff here
    }
    else
    {
        // don't do stuff here
    }
}

【讨论】:

    猜你喜欢
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    相关资源
    最近更新 更多