委托函数返回可为空值的问题
Problem with a delegate function returning a nullable value
我有以下代码:
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 方法的委托有一个 return 类型的 T?
应该转换为 decimal?
即正是在我使用 returns 的委托时。然而,错误消息似乎表明编译器期望委托 return 是一个不可为 null 的小数。
为什么会出现此错误,我该如何解决?
我根据您的代码创建了一个可重现的示例:
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?)
)returns a 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 syntax but 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?
(即摆脱可为 null 的引用类型语法),则会出现相同的问题:
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?)
);
}
}
我有以下代码:
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 方法的委托有一个 return 类型的 T?
应该转换为 decimal?
即正是在我使用 returns 的委托时。然而,错误消息似乎表明编译器期望委托 return 是一个不可为 null 的小数。
为什么会出现此错误,我该如何解决?
我根据您的代码创建了一个可重现的示例:
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?)
)returns a 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 syntax but 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?
(即摆脱可为 null 的引用类型语法),则会出现相同的问题:
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?)
);
}
}