System.NullReferenceException 使用空合并运算符时

System.NullReferenceException when using null coalescing operator

我 运行 遇到了一个似乎无法修复的错误。在对 Stack Overflow 进行了一些研究之后,空合并运算符似乎可以解决我的问题,但它并没有帮助。这是给出错误的代码:

List<OperationsReviewLevelResult> results = new List<OperationsReviewLevelResult>();
foreach (var approval in OperationsReviewers.ApprovalItems)
{
     var result = new OperationsReviewLevelResult();
     result.ApproverName = approval.Results.FirstOrDefault().Name ?? "";
     result.ReviewLevel = approval.Name;
     result.Comment = approval.Results.FirstOrDefault().Comments ?? "";
     results.Add(result);
}

当我 运行 这段代码时,我得到:

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

来自 result.ApproverName = approval.Results.FirstOrDefault().Name ?? ""; 行。我添加了空合并运算符来检查空值,但这并没有解决我的问题。错误是因为没有 Results 批准所以我假设 FirstOrDefault linq 方法将 return 默认值,并且当它意识到默认值对 [=15 具有空值时=],它将使用空合并运算符 return 运算符右侧的 "" 空字符串。

如果我遗漏了什么,请告诉我,因为我似乎无法理解为什么即使在添加空合并运算符时也会出现此错误。

编辑:正如评论中所建议的那样,查看 this post 帮助我更多地了解了我收到此错误的原因。虽然问题有点不同,但我强烈建议阅读答案以全面了解我的问题。

在每个 .FirstOrDefault() 调用之后,您需要添加 ?. 运算符。这是一个完整的解决方案:

List<OperationsReviewLevelResult> results = new List<OperationsReviewLevelResult>();
foreach (var approval in OperationsReviewers.ApprovalItems)
{
     var result = new OperationsReviewLevelResult();
     result.ApproverName = approval.Results.FirstOrDefault()?.Name ?? "";
     result.ReviewLevel = approval.Name;
     result.Comment = approval.Results.FirstOrDefault()?.Comments ?? "";
     results.Add(result);
}

如果结果的其他部分可能为空,您可以走完整的偏执路线

List<OperationsReviewLevelResult> results = new List<OperationsReviewLevelResult>();
foreach (var approval in OperationsReviewers.ApprovalItems)
{
     var result = new OperationsReviewLevelResult();
     result.ApproverName = approval?.Results?.FirstOrDefault()?.Name ?? "";
     result.ReviewLevel = approval?.Name;
     result.Comment = approval?.Results?.FirstOrDefault()?.Comments ?? "";
     results.Add(result);
}

偏执狂和 LINQ 化:

var results = OperationsReviewers.ApprovalItems
    .Select(approval => new OperationsReviewLevelResult
    {
        ApproverName = approval?.Results?.FirstOrDefault()?.Name ?? "",
        ReviewLevel = approval?.Name,
        Comment = approval?.Results?.FirstOrDefault()?.Comments ?? ""
    }
    .ToList();

最可能的原因是FirstOrDefault()returnsnull(作为默认值值),因此 FirstOrDefault().Name 抛出异常。 您可以在 ?.

的帮助下尝试 null propagation
   foreach (var approval in OperationsReviewers.ApprovalItems)
     results.Add(new OperationsReviewLevelResult() {
       ApproverName = approval.Results.FirstOrDefault()?.Name ?? "",
       ReviewLevel  = approval.Name,
       Comment      = approval.Results.FirstOrDefault()?.Comments ?? "",
     });

所以如果 approval.Results 并且因此 FirstOrDefault() returns null 那么 FirstOrDefault()?.Name returns null 最后变成 ""