【问题标题】:Unable to safely detect null value without nullable warnings无法在没有可空警告的情况下安全地检测空值
【发布时间】:2021-07-22 17:06:12
【问题描述】:

我不太明白以下可为空的警告。

如您所见,我有一部分表达式,其中sheet 不为空,但sheet.Id 可能为空。但是为什么我用sheet.Id.HasValue查不到呢?

我也尝试过sheet.Id != null,但这给了我一个不同的警告。

警告 CS8625 无法将 null 文字转换为不可为 null 的引用类型。

如何安全地确定sheet.Id 是否不为空?

更新

这个版本实际上是在没有警告的情况下编译的。但我还是不明白为什么其他版本给我警告。

public Worksheet? GetFirstWorksheet()
{
    WorkbookPart? workbookPart = Document.WorkbookPart;
    Workbook? workbook = workbookPart?.Workbook;
    if (workbook != null)
    {
        Sheets? sheets = workbook.GetFirstChild<Sheets>();
        Sheet? sheet = sheets?.Elements<Sheet>()
            .FirstOrDefault();
        if (sheet != null && sheet.Id?.Value != null)
            return ((WorksheetPart)workbookPart!.GetPartById(sheet.Id!)).Worksheet;
    }
    return null;
}

【问题讨论】:

  • 您可以尝试使用空条件if(sheet?.Id != null)
  • 其次,所有可为空的对象是什么?
  • @Nkosi:这也给了我警告 CS8604 和 CS8625。
  • @Nkosi:你什么意思? Sheet 是 OpenXml 的一部分。该库的开发人员决定什么可以为空。我只是想处理它。您应该尝试使用 OpenXml 和可空值进行复杂开发。有趣的东西!
  • 嗯,这真的很奇怪。如果你这样做会发生什么if (sheet?.Id.HasValue == true)

标签: c# .net-core openxml nullable


【解决方案1】:

你可以组合

        if (sheet != null && sheet.Id?.Value != null)
            return ((WorksheetPart)workbookPart!.GetPartById(sheet.Id!)).Worksheet;

转换成一个等价的表达式:

         if (sheet?.Id?.HasValue == true)
            return ((WorksheetPart)workbookPart!.GetPartById(sheet.Id!)).Worksheet;

         if (sheet?.Id?.Value != null)
            return ((WorksheetPart)workbookPart!.GetPartById(sheet.Id!)).Worksheet;

我不确定为什么编译器不够聪明,无法意识到在您的表达式的某些术语中,某些字段可能不再为空。

顺便说一句,根据你想去的可空链兔子洞多远,你可以重写图像中的代码,看起来像这样:

Worksheet? GetWorksheet(string name)
{
    WorkbookPart? workbookPart = Document.WorkbookPart;
    Worksheet? sheet = workbookPart?.Workbook
        .GetFirstChild<Sheets>()?.Elements<Sheet>()
        .Where(s => string.Compare(s.Name, name, true) == 0 && s.Id?.HasValue == true)
        .Select(s => ((WorksheetPart) workbookPart!.GetPartById(s.Id!)).Worksheet)
        .FirstOrDefault();
    return sheet;
}

Worksheet? GetWorksheet(string name)
{
    WorkbookPart? workbookPart = Document.WorkbookPart;
    return workbookPart?.Workbook
        .GetFirstChild<Sheets>()?.Elements<Sheet>()
        .Where(s => string.Compare(s.Name, name, true) == 0 && s.Id?.HasValue == true)
        .Select(s => ((WorksheetPart) workbookPart!.GetPartById(s.Id!)).Worksheet)
        .FirstOrDefault();
}

【讨论】:

  • 中间那句没看懂。如果sheet?.Id 为空,那么sheet?.Id?.HasValue 怎么不为空?另外,有趣的是,我仍然需要的最后一个 ! 是 return 子句。
  • 中间,如果sheet?.Idnull,那么左边是null,不能等于true
猜你喜欢
  • 2010-11-08
  • 1970-01-01
  • 2014-07-09
  • 2011-05-23
  • 1970-01-01
  • 2021-04-19
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
相关资源
最近更新 更多