没有可空警告无法安全检测空值
Unable to safely detect null value without nullable warnings
我不太理解以下可为空的警告。
如您所见,我有一个表达式的一部分,其中 sheet
不为空,但 sheet.Id
可能为空。但是为什么我用sheet.Id.HasValue
查不到呢?
我也试过 sheet.Id != null
,但这给了我一个不同的警告。
Warning CS8625 Cannot convert null literal to non-nullable reference type.
如何安全地确定 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 != 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
不为空,但 sheet.Id
可能为空。但是为什么我用sheet.Id.HasValue
查不到呢?
我也试过 sheet.Id != null
,但这给了我一个不同的警告。
Warning CS8625 Cannot convert null literal to non-nullable reference type.
如何安全地确定 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 != 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();
}