提问人:russ 提问时间:6/30/2023 最后编辑:Mustafa Özçetinruss 更新时间:7/15/2023 访问量:104
在不使用抑制字符的情况下,如何避免从文件中读取一行文本时出现空警告?
How can I avoid a null warning when reading a line of text from a file, without using a supression character?
问:
我最近使用 创建了一个新的 Windows 窗体项目。NET6 - 并收到很多“空”警告(例如)。从我发现的其他帖子中,我看到我可以通过同时禁用可为 null 的警告或在适当的位置添加问号和感叹号来消除警告。这两个选项似乎只是掩盖了潜在的问题,我想知道以下代码示例是否有更好的解决方案。CS8600: Converting null literal or possible null value to non-nullable type.
String LineText, filename, bin, binname;
String[] codes;
InkFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
if (InkFileDialog.ShowDialog() == DialogResult.OK)
{
StreamReader inkfile = new StreamReader(InkFileDialog.FileName);
while ((LineText = inkfile.ReadLine()) != null)
{
}
在第一个示例的 while 语句中,“inkfile.ReadLine()“给出 CS8600 警告(如上所述)。
String LineText, filename, bin, binname;
String[] codes;
InkFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
if (InkFileDialog.ShowDialog() == DialogResult.OK)
{
StreamReader inkfile = new StreamReader(InkFileDialog.FileName);
if (inkfile.EndOfStream)
{
MessageBox.Show("Ink file is empty.");
return;
}
else
{
// Read header lines from the file
while (!(LineText = inkfile.ReadLine()).Contains("RowData"))
{
在第二个示例的语句中,给出了相同的警告,加上 .while
LineText = infile.ReadLine()
CS8600
CS8602: Dereference of a possibly null reference
人们提到执行 null 检查,但我无法找到使用我拥有的 while 循环来完成此操作的方法。
答:
你怀疑一起禁用警告是正确的 - 添加这些警告是为了让您知道代码中的潜在错误,而禁用它们会隐藏这一点。Null 以及扩展的 NullReferenceException 被其创建者描述为“他的十亿美元错误”。就我个人而言,我甚至比默认设置更进一步,将警告提升为错误,以便在我解决这些问题之前不会构建我的代码,这使得 NullReferenceExceptions(几乎)不可能。
第一个示例中的问题是,您分配了一个可为 null 的类型(返回到一个不可为 null 的变量。因此,编译器将假定所有将来对 的引用也可能为 null,并且正如你所发现的那样,您将一直收到警告。ReadLine()
LineText
LineText
第二个示例进一步演示了这一点,因为编译器已(正确)确定,如果返回 null,则对 的调用可能会导致 NullReferenceException。.Contains("RowData")
ReadLine()
这里重要的是编译器是正确的,它会警告你代码中的潜在错误;你应该听它,并处理这些错误。一种方法是将可空性应用于相关变量。?
您还可以使用其他语言/框架功能来“教导”编译器什么是安全的。编译器在这里关注的是,您可能会尝试在 while 循环之外进行访问——在循环中,值可能永远不会为 null,但任何后续代码都不会有相同的保证。因此:LineText
- 如果 的值只在循环内部访问,则可以将代码简化为,编译器将理解循环内部的值永远不会为 null。
LineText
while (inkfile.ReadLine() is string lineText) { /* code accessing lineText */ }
lineText
- 同样,将对第二个示例产生相同的影响。
while (inkfile.ReadLine() is string lineText && lineText.Contains("RowData")) { /* code accessing lineText */ }
- 另一方面,如果结果将在循环之外使用,请监听编译器并应用编译器,以便它可以正确地完成其工作。
LineText
?
最后,避免使用 因为这会有效地禁用单个警告,并且似乎只存在于编译器无法以其他方式确信值不能为 null 的实例中。这些实例在 .NET 的每个版本中都很少见,因为添加了新功能,使可为 null 的上下文清晰。!
希望这对:)有所帮助
评论
LineText
LineText = lineText
评论
LineText
String
ReadLine
null
LineText
null
else
return
StreamReader inkfile = new StreamReader(InkFileDialog.FileName);
using var inkfile = new StreamReader(InkFileDialog.FileName);