问题描述
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
而不是 T
和 T?
(即摆脱可为空引用类型语法),也会出现同样的问题:
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?)
);
}
}