如何简单安全地使用await调用可空的Func<Task>委托?
方案1:空条件运算符 + null 合并运算符(C# 6+ 首选)
这是最简洁的等价写法,不需要改原有逻辑,一行就能实现相同效果:
public async Task Test() { Func<Task> funcWithTask = null; await (funcWithTask?.Invoke() ?? Task.CompletedTask); }
逻辑说明:
funcWithTask?.Invoke()会先自动判断委托是否为null:不为null就正常执行返回对应Task,为null则直接返回null?? Task.CompletedTask会把前一步返回的null替换为已完成的默认Task,保证await的对象永远有效,不会触发空引用异常
方案2:封装扩展方法(高频调用场景推荐)
如果项目里频繁需要调用可能为null的Func<Task>类委托,可以封装通用扩展方法,后续调用更简洁:
先定义扩展类:
public static class FuncTaskExtensions { public static Task InvokeOrDefault(this Func<Task> func) { return func?.Invoke() ?? Task.CompletedTask; } // 有入参的委托也可以按需加重载,比如带一个参数的版本: public static Task InvokeOrDefault<T>(this Func<T, Task> func, T param) { return func?.Invoke(param) ?? Task.CompletedTask; } }
调用时完全不需要处理null判断:
public async Task Test() { Func<Task> funcWithTask = null; await funcWithTask.InvokeOrDefault(); }
注意提醒
不要省略null合并运算符直接写await funcWithTask?.Invoke(),如果委托为null时await的对象就是null,会直接抛出NullReferenceException。
内容的提问来源于stack exchange,提问作者Master Silver
相关产品推荐
相关产品推荐

