10

我想发表以下声明:

var block = blocksById.FirstOrDefault(X => X.Value == tracResult.ID).Key

我的问题是如果我有 FirstOrDefault 空值,如何更正确地处理它。我只是不觉得if陈述是唯一可以在这里的解决方案......

4

1 回答 1

24

由于引入了null 条件运算符 (?),它很简单:

var block = blocksById.FirstOrDefault(X => X.Value == tracResult.ID)?.Key;

请记住,在这种情况下,即使Valueis an intblock也将是 type Nullable<int>,因此可以是null

但是,如果您想要分配一个默认值 ifnull返回,您可以使用null 合并运算符 (??)是这样的:

var block = blocksById.FirstOrDefault(X => X.Value == tracResult.ID)?.Key ?? 6;

然而,对于更复杂Select的陈述,以下仍然有效......


前一段时间...

将其拆分为WhereSelect

var block = blocksById.Where(x => x.Value == tracResult.ID)
                      .Select(x => x.Key)
                      .FirstOrDefault();

这样,如果 FirstOrDefault 返回,您将不会收到 NullRefferenceException null

或者,您可以给它一个默认值,如下所示:

var block = blocksById.Where(x => x.Value == tracResult.ID)
                      .Select(x => x.Key)
                      .FirstOrDefault() ?? somedefaultvalue;

或者正如@Silvermind 对不可空到可空类型(int's)所述:

var block = blocksById.Where(x => x.Value == tracResult.ID)
                      .Select(x => (int?) x.Key)
                      .FirstOrDefault() ?? somedefaultvalue;

更新:有些人似乎怀疑这是一个有效的用例,并认为必须稍后在程序中完成对 null 的检查。

虽然在很多情况下都是如此,但并不总是如此,或者如果是这样,那么这种方式可能更方便。

一些例子:

//one liner, null check delegated (not my favorite): 
return SomeCalculatedValue(collection.Where(condition).Select(selection).FirstOrDefault());

//or a mapping (shown with default value):
var result = collection.Where(condition)
                       .Select(c => 
                           { 
                                Foo = c.Foo,
                                Bar = c.Bar
                           }).FirstOrDefault()) ?? new { Foo = "New", Bar = "Empty"};
于 2013-11-13T07:11:38.720 回答