可能重复:
Nullable types and the ternary operator. Why won’t this work?
这是我的代码
public decimal? Get()
{
var res = ...
return res.Count() > 0 ? res.First() : (decimal?) null;
}
而且这个不起作用
public decimal? Get()
{
var res = ...
return res.Count() > 0 ? res.First() : null;
}
给出编译器错误:
错误1无法确定条件表达式的类型,因为'decimal'和'
<null>
'之间没有隐式转换
我想知道为什么?任何想法?
答案 0 :(得分:7)
此行为在C#语言规范的第7.13节中介绍。
简而言之,三元运算符中两个表达式的类型必须是* * *,以便编译器确定三元表达式的类型。在这种情况下,正在考虑的两种类型是
decimal
null
decimal
类型是值类型,因此null不可转换为它。值null
没有关联类型。这可以防止编译器确定表达式的类型并导致编译错误。
在第一个示例中,第二个类型是decimal?
。 decimal
和decimal?
之间存在转换,因此编译器会选择decimal?
作为类型。
答案 1 :(得分:2)
错误很清楚。这俩 ”?” en“:”该条件运算符的部分需要具有相同的类型,或者必须至少隐式转换为相同的Type。单独的null
没有良好的类型。
也许你可以使用.FirstOrDefault()。取决于res
或null
的{{1}}类型。
答案 2 :(得分:2)
偏离主题,但......
当你需要知道的是序列是否有任何元素时,使用Count
是没有意义的。 Count
会遍历所有元素,而Any
会在遇到第一个元素后立即停止:
public decimal? Get()
{
var res = ...
return res.Any() ? res.First() : (decimal?)null;
}
或许这个:
public decimal? Get()
{
var res = ...
using (var e = res.GetEnumerator())
{
return e.MoveNext() ? e.Current : (decimal?)null;
}
}
答案 3 :(得分:1)
我猜res是一个十进制数组,即decimal []。这是因为你已经声明了这样的res:
var res = { 1.0, 2.0, 3.0 };
而不是这样:
var res = { 1.0, 2.0, null };
所以编译器没有理由认为res是一个可以为空的小数组数组。
现在您正在使用三元运算符,它必须始终从两侧返回相同(或等效的可浇注)类型。
但是因为res.First()是'decimal'而且你的null默认是无类型的,它只会使你的null等同于你的第一个参数的类型(res.First(),即十进制)。通过强制将null键入为可空的十进制('decimal?'),您实际上是强制编译器将res.First()视为可以为空的十进制数。
然而,总体上更适合您的解决方案是:
public decimal? Get()
{
decimal?[] res = ...
return res.FirstOrDefault();
}
答案 4 :(得分:0)
在第二种情况下,您可以使用res.FirstOrDefault()
。
IEnumerable<T>.FirstOrDefault()
在集合中返回第一个T
,如果设置为空则返回default<T>
:null
表示类和结构的一些默认值,通常情况下为{{1} }。
0
等于
public decimal? Get()
{
var res = ...
return res.FirstOrDefault();
}