You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写无空值异常的Linq查询,高效筛选满足条件的GameObject

Linq筛选Unity GameObject的规范实现

现有代码的可优化点

你之前拆分两个Where的写法虽然能正常规避空引用,但存在两个明确的性能与可读性问题:

  • 重复组件查询:对同一个GameObject连续两次调用GetComponent<Cars>(),而Unity的GetComponent本质是遍历对象挂载组件的查找操作,重复调用会产生不必要的查找开销
  • 冗余遍历流程:拆分两个Where意味着框架需要对m_ItemList的元素完成两次全量遍历,远低于单次遍历的执行效率

推荐实现方案

最高效的零重复查询写法

通过Linq的投影操作缓存组件引用,彻底避免重复查找:

itemBought = m_ItemList
    .Select(go => new { TargetGo = go, CarComponent = go.GetComponent<Cars>() })
    .Where(item => item.CarComponent != null && item.CarComponent.Bought)
    .Select(item => item.TargetGo)
    .ToList();

实现优势:

  • 每个GameObject仅执行一次GetComponent<Cars>(),无重复查询的性能损耗
  • 空判断前置,组件不存在时直接跳过后续判断,从根源上避免空引用异常
  • 单次遍历完成全部筛选逻辑,执行效率和最初的一次性Where写法持平

新手友好的简洁写法

利用C#空条件运算符压缩判断逻辑,代码可读性更强:

itemBought = m_ItemList
    .Where(go => go.GetComponent<Cars>()?.Bought == true)
    .ToList();

写法注意点:

  • 空条件运算符?.会在GetComponent<Cars>()返回null时直接终止后续属性访问,完全不会触发空引用
  • 由于Bought是bool值类型,?.Bought最终返回的是可空bool类型,必须显式和true做等值判断,否则会出现类型不匹配的编译报错

避坑提醒

  • 不要为了压缩代码把同一个GetComponent调用散落到多个判断分支里,哪怕逻辑通顺,重复的组件查找也会在列表元素较多时积累明显的性能损耗
  • 只要列表中混有不同挂载类型的GameObject,就必须在访问组件属性前增加非空判断,不要依赖"组件必然存在"的假设

内容的提问来源于stack exchange,提问作者user15199268

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 18:36:08