微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

委托函数返回可为空值的问题

如何解决委托函数返回可为空值的问题

我有以下代码

private T? FromCache<T>(CacheKey key,Func<T?> retriever)
{
    if (cache.TryGetValue(key,out T res))
        return res;
    res = retriever();
    if (res is not null)
        cache.Set(key,res);
    return res;
}

public decimal? GetClosingExchangeRate(string sourceCurrencyCode,string targetCurrencyCode)
{
    return FromCache<decimal>(CacheKey.Closing(sourceCurrencyCode,targetCurrencyCode),// The following line results in this error:
            // Error CS0266  Cannot implicitly convert type 'decimal?' to 'decimal'.An explicit conversion exists (are you missing a cast?)
            () => GetExchangeRate(sourceCurrencyCode,targetCurrencyCode)?.ClosingRate
        );
}
public ExchangeRateDeFinition? GetExchangeRate(string sourceCurrencyCode,string targetCurrencyCode)
{
    return GetExchangeRateQuery(sourceCurrencyCode,targetCurrencyCode).FirstOrDefault();
}
public class ExchangeRateDeFinition
{
    [...]
    public decimal? ClosingRate { get; set; }
    [...]
}

在这种情况下,

我不明白错误:据我所知,传递给 FromCache 方法的委托的返回类型为 T?,它应该转换为 decimal?,这正是我使用委托的时间返回。然而,错误消息似乎表明编译器期望一个委托返回一个不可为空的小数。

为什么我会收到这个错误,我该如何解决

解决方法

我根据您的代码创建了一个可重现的示例:

internal class NullableExample
{
    private T? FromCache<T>(System.Func<T?> retriever)
    {
        return retriever();
    }

    public decimal? GetClosingExchangeRate()
    {
        return FromCache<decimal>(
                // The following line results in this error:
                // Error CS0266  Cannot implicitly convert type 'decimal?' to 'decimal'.An explicit conversion exists (are you missing a cast?)
                () => default(decimal?)
            );
    }
}

问题在于您对 FromCache<decimal> 的调用:

您指定的类型参数是 decimal 但是

GetExchangeRate(sourceCurrencyCode,targetCurrencyCode)?.ClosingRate

(我简化为 default(decimal?))返回一个 decimal?

你需要改变

FromCache<decimal>

FromCache<decimal?>

或者你可以省略类型参数并有

return FromCache(
        // The following line results in this error:
        // Error CS0266  Cannot implicitly convert type 'decimal?' to 'decimal'.An explicit conversion exists (are you missing a cast?)
        () => default(decimal?)
    );

因此编译器可以确定您正在调用 FromCache<decimal?>


根本问题是您使用的是 nullable reference type 语法但 Decimal is a struct 所以在将 ` 传递给

private T? FromCache<T>(System.Func<T?> retriever)

编译器看到

private decimal FromCache<decimal>(System.Func<decimal> retriever)

代替

private decimal? FromCache<decimal>(System.Func<decimal?> retriever)

如您所料。

您可以通过查看 Intellisense 所说的内容(在 Visual Studio 中)看到这一点:

如果您让 FromCache 使用 T 而不是 TT?(即摆脱可为空引用类型语法),也会出现同样的问题:

internal class NullableExample
{
    private T FromCache<T>(System.Func<T> retriever)
    {
        return retriever();
    }

    public decimal? GetClosingExchangeRate()
    {
        return FromCache<decimal>(
                // The following line results in this error:
                // Error CS0266  Cannot implicitly convert type 'decimal?' to 'decimal'.An explicit conversion exists (are you missing a cast?)
                () => default(decimal?)
            );
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。