GetOrCreateAsync
对于IMemoryCache
的扩展方法:
public static async Task<TItem?> GetOrCreateAsync<TItem>(this IMemoryCache cache, object key, Func<ICacheEntry, Task<TItem>> factory)
{
if (!cache.TryGetValue(key, out object? result))
{
using ICacheEntry entry = cache.CreateEntry(key);
result = await factory(entry).ConfigureAwait(false);
entry.Value = result;
}
return (TItem?)result;
}
为什么他们返回
TItem?
而不是仅仅 TItem
?假设我的 factory
方法永远不会返回 null,那么可以安全地假设它永远不会是 null
并使用 null-forgiving 运算符 !
忽略它吗?
public async Task<Foo> GetFooAsync()
=> (await cache.GetOrCreateAsync("Foo", async _ => new Foo()))!
这篇 github 帖子 有一些重要因素解释了为什么他们选择将其设为可为空的返回类型。 这里有一些需要考虑的事情。
可以根据eerhardt缓存空值。
Stephen Toub 在帖子中指出以下内容:
我们对核心库中可空注释的首要原则之一是,它们永远不应该撒谎并说空不是可能的结果,而实际上它是可能的。这确实会导致某些情况下方法被注释为返回 T?即使 null 很少见或属于极端情况,例如Activator.CreateInstance 返回 T?因为例如,如果您指定 Nullable 作为类型,它实际上可以为 null,但这意味着可以信任返回值的可为空性:如果它说它不可为 null,那么它永远不会为 null,并且调用者不会不需要防止取消引用 null。 https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/api-guidelines/nullability.md中概述了这些原则。
我希望这可以清楚地说明为什么他们选择将其设为可为空。 在您的情况下,如果您 100% 确定不会缓存任何可空值,那么理论上您可以忽略它可以返回空值的事实。尽管我不建议在任何情况下使用它,但您的程序会增长/更改并要求这是可能的。
如果 Factory 方法以外的其他方法使用该键将 null 值缓存到
IMemoryCache
中,则可能会返回 null。这就是为什么它在技术上是有效和可能的。