重复使用null条件运算符(?.)是否会产生性能损耗?
关于null条件运算符(?.)的性能疑问
先看两段实现相同逻辑的C#代码:
第一段(使用?.运算符)
return new Notification() { ChannelId = data?.Channel?.ChannelID, GatewayType = data?.Channel?.PrimaryGW?.Type, PaymentMethod = data?.GatewayTransaction?.PaymentMethodTypes.ToString(), PaymentType = data?.GatewayTransaction?.PaymentType.ToString(), Data = data, };
第二段(使用if判空)
var notification = new Notification(); if (data != null) { if (data.Channel != null) { notification.ChannelId = data.Channel.ChannelID; notification.GatewayType = data.Channel.PrimaryGW.Type; } if (data.GatewayTransaction != null) { notification.PaymentMethod = data.GatewayTransaction.PaymentMethodTypes.ToString(); notification.PaymentType = data.GatewayTransaction.PaymentType.ToString(); } notification.Data = data; } return notification;
问题
第一段代码中重复对同一对象使用null条件运算符(?.),相比第二段的if判空写法,大量使用?.是否会带来性能开销?作为开发者,常为避免编写if语句而大量使用?.,这种做法是否会有性能代价?
性能开销分析
底层实现差异
C#的?.运算符编译后会生成包含null检查的IL代码,但和手动if判空存在细微区别:- 手动if判空会对同一对象仅做一次null校验,比如第二段中
data != null判断一次后,后续直接访问data.Channel; - 第一段里
data?.Channel?.ChannelID和data?.Channel?.PrimaryGW?.Type会分别对data和data.Channel做两次null检查——重复的?.会导致同一对象被多次判空。
- 手动if判空会对同一对象仅做一次null校验,比如第二段中
实际性能影响
在绝大多数业务场景下,这种性能差异完全可以忽略。现代JIT编译器会对重复的null检查做优化,比如合并同一对象的多次判空逻辑,最终生成的机器码和手动if判空的差距极小。只有在极端高频调用的场景(如百万级循环内),才可能测出细微的性能差别,但这类场景在日常开发中极少出现。代码维护性的权衡
?.的核心优势是代码简洁、可读性高,避免了嵌套if带来的“金字塔代码”。虽然重复使用存在理论上的微小性能开销,但相比代码维护成本的降低,这种代价在绝大多数情况下是值得的。如果确实担心重复检查的问题,可以先做一次null判断,将非空对象缓存到局部变量中再链式访问属性——比如先判断data?.Channel不为空,再把data.Channel赋值给局部变量,后续直接用该变量访问属性,既保留简洁性,又避免重复null检查。
总结
- 理论上,重复使用
?.会产生少量性能开销,但实际业务场景中几乎感知不到; - 优先考虑代码的可读性和维护性,
?.是推荐写法; - 极端性能敏感场景下,可通过缓存非空对象的方式减少重复null检查。
内容的提问来源于stack exchange,提问作者Chandra Mohan
相关产品推荐
相关产品推荐

