2010-08-13 51 views
6

据我所知,如果记录集是空的,linq方法FirstOrDefault()返回null。为什么不能使用??运算符来对付这个函数?像这样:FirstOrDefault()无法与? operator

Double d = new Double[]{}.FirstOrDefault() ?? 0.0; 


更新

我不想检查,如果dnull在我后面的代码上。而这样做的:

Double d new Double[]{}.FirstOrDefault() == null 
     ? 0.0 
     : new Double[]{}.FirstOrDefault(); 

...或:

var r = new Double[]{}.FirstOrDefault(); 

Double d = r == null ? 0.0 : r; 

...似乎有点矫枉过正 - 我倒是喜欢做这个空支票的一行代码。

+0

当你测试的时候,你可以用'default(double)'替换'new Double [] {}。FirstOrDefault();'。 – Kobi 2010-08-13 11:50:39

回答

10

其实,FirstOrDefault<T>()返回T,这是一个值或default(T)

default(T)为值类型要么null(T)0(如double

11

因为空合并运算符(??)仅适用于可空引用类型,而Double是值类型。您可以使用可为空的双精度(double?)。

+6

即使这样做,“?? 0.0”在这种情况下是多余的。 – FuleSnabel 2010-08-13 11:45:26

+1

@FuleSnabel,绝对,因为'0.0'是无论如何都是默认值。 – 2010-08-13 11:46:22

1

使它nullable应该工作。但是,那么你使它nullable,一切都取决于你的场景......

Double d = new Double?[] { }.FirstOrDefault() ?? 0.0; 
5

的方法被称为FirstOrDefault不FirstOrNull,即,其将返回0,双反正的默认值,所以没有必要为??。

+0

会接受你的答案。但詹姆斯库伦提供了一个更详细的。谢谢Ben。 – roosteronacid 2010-08-13 12:02:37

0

虽然其他人已经回答了你为什么在这里遇到编译问题,但你说得对,这对于值类型是有问题的。据我所知,在这种情况下无法知道零结果是因为第一个项目是否为零,或者因为IEnumerable<double>是空的。

在你给的例子中,回退值为零,无论如何,所以你需要的是:

var r = new double[]{...}.FirstOrDefault(); 

假设你有一个非零回退值,你有几种选择:

var r = !myDoubles.Any() ? fallback : myDoubles.First(); 

var r = myDoubles.Cast<double?>().FirstOrDefault() ?? fallback; 

如果你有Zen Linq Extensions,你可以这样做:

var r = myDoubles.FirstOrFallback(fallback);