为什么 IMemoryCache.GetOrCreateAsync 返回“TItem”? (可为空)而不是“TItem”?

问题描述 投票:0回答:2

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()))!
c# .net nullable-reference-types memorycache
2个回答
10
投票

这篇 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% 确定不会缓存任何可空值,那么理论上您可以忽略它可以返回空值的事实。尽管我不建议在任何情况下使用它,但您的程序会增长/更改并要求这是可能的。


0
投票

如果 Factory 方法以外的其他方法使用该键将 null 值缓存到

IMemoryCache
中,则可能会返回 null。这就是为什么它在技术上是有效和可能的。

© www.soinside.com 2019 - 2024. All rights reserved.