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

C#使用Func表达式调用OrderBy排序时空引用异常问题

问题原因
  • 空值判断逻辑完全写反:你使用了逻辑与&&拼接判断条件,仅当Recipient和Address同时为null时才会返回空值。只要Recipient不为null、哪怕Address是null,判断结果都会为false,直接进入后续的属性访问逻辑,触发空引用。这也是你把返回值从null换成string.Empty依然报错的核心原因——空对象的属性访问根本没走到你写的返回默认值的分支。
  • 选择dynamic作为排序键返回类型会引入额外异常:当排序字段是值类型(比如数字类型的Nummer)时,编译器会自动生成装箱逻辑,而三元表达式返回的null是无类型引用类型,两者类型不匹配,在EF Core等非内存LINQ提供程序下会直接抛出执行异常。
  • 你漏了对最上层Inhalt属性的空判断,该属性为null时同样会触发空引用。
修复方案

把表达式列表的泛型参数从dynamic改成object(排序仅要求键实现IComparable接口,object完全兼容,不会引入dynamic的绑定开销和类型问题),直接使用C#内置的空条件运算符?.即可生成正确的逐层短路空判断逻辑,不需要手动写三元判断:

List<Expression<Func<Data, object>>> orderingExpression = new List<Expression<Func<Data, object>>>();
// 空条件运算符会自动逐层判断空,任意节点为null就直接返回null,不会访问下级属性
orderingExpression.Add(x => x.Inhalt?.Recipient?.Address?.Nummer);
orderingExpression.Add(x => x.Inhalt?.Recipient?.Address?.Street);

// 原有排序调用逻辑无需修改
datatemp = datatemp.OrderBy(orderingExpression.First()).ThenBy(orderingExpression.Last());

如果你使用的LINQ提供程序版本过老不支持空条件运算符,手动写判断时注意使用逻辑或||实现短路逻辑,同时将属性值统一转成object保证三元表达式两个分支类型一致:

orderingExpression.Add(x => 
    x.Inhalt == null 
    || x.Inhalt.Recipient == null 
    || x.Inhalt.Recipient.Address == null 
    ? null 
    : (object)x.Inhalt.Recipient.Address.Nummer
);
orderingExpression.Add(x => 
    x.Inhalt == null 
    || x.Inhalt.Recipient == null 
    || x.Inhalt.Recipient.Address == null 
    ? null 
    : (object)x.Inhalt.Recipient.Address.Street
);

注意:逻辑或||是短路运算符,只要前面的条件成立(比如判断到Inhalt为null),就不会执行后面的属性访问逻辑,从根源上避免空引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:02:01