C# 的一些问题操作

发表于: 10/28/2021

言尽于行

C Sharp

await

nullable

前情提要

作为async await关键字源头的C#,搞些异步操作已经是很舒心的了,不过近来.Net 6就要出了,新版本里默认启用了nullable特性,当享受着全局的空安全的时候,可能莫名其妙的发现有些地方出现了碍眼的++绿色下划波浪线++{.wavy .success}。 :anger:

问题

问题代码多半是这样:

await something?.BalaBala();

然后警告你{解引用了一个可能为空的引用^Dereference of a possibly null reference}。 这是因为?.操作符在变量为null的时候会把自己整段都变为null,也就是说整个await等待了一个Task<ReturnType>?,而目前的await并不想等待一个寂寞。1

Workaround

作为有些许追求的人,一定要找个比较优雅的写法,结合了一些观察学习,我的答案是:

public static class FunExt{
    public static Task SafeExecute(this Task? task) { return (task?? Task.Delay(0)); }
}

考虑到可能的执行失败时需要默认值的情况,可以加一个这个: 2 !!?强烈怀疑,真的会有这种需求吗!!

public static Task<T?> SafeExecute<T>(this Task<T?>? task) => task ?? Task.FromResult(default(T));

使用方式为:

await (something?.BalaBalaA()).SafeExcute();

虽然还是没能避免多加一对括号,不过总比去进行麻烦的判断要好了那么一点。

Footnotes

  1. 确实有这么一个新特性的提议,我开始看了觉得不明所以,直到自己被警告秀了一脸

  2. 原写法来自 StackOverflow 不过其并未考虑到default(T)的类型为T?