请考虑以下几点:
var lines = new List<string>();
string path = "FileName.txt";
var reader = File.OpenText(path);
while (!reader.EndOfStream)
{
lines.Add(reader.ReadLine());
}
在csproj中,将Nullable
标志设置为enable
时,reader
是给出Possible null reference argument for parameter 'item'
编译器警告的StreamReader?
。即使我显式地将reader
设置为StreamReader
,问题仍然存在。
有没有办法绕过这个警告而不关闭Nullable
?
发布于 2020-07-21 09:44:46
您可以将所有这些代码缩减为两行Nullable代码:
string path = "FileName.txt";
var lines = File.ReadLines(path).ToList();
发布于 2020-07-20 00:22:22
我相信,问题的描述中所包含的警告并不充分。我复制了这个问题,得到了下一个编译器警告:CS8604 Possible null reference argument for parameter 'item' in 'void List<string>.Add(string item)
。警告发生在下一行。
lines.Add(reader.ReadLine());
因为List<string> lines
是不可空string
值的列表,而StreamReader.ReadLine()
方法可以返回可空的string?
(参见参考源)。因此,在上面的代码行中,这是将null
字符串值添加到不可空字符串列表中的尝试。
要解决这个问题,可以使用以下任何一种方法:
reader.ReadLine()
的结果不能是null
,因为它是在流结束时执行的。因此,可以使用null-宽恕操作符来抑制警告:
lines.Add(reader.ReadLine()!);reader.ReadLine()
检查表达式的结果是否为null。如果使用下一段代码,则警告将消失:
弦乐?line = reader.ReadLine();if (line != null) lines.Add(行);更新
正如@IanRingrose在注释中指出的那样,可以在循环中使用条件line != null
而不是条件!reader.EndOfStream()
。使用这种条件解决方案可以更清楚地说明:
string? line;
while ((line = reader.ReadLine()) != null)
{
lines.Add(line);
}
现在,我们不需要在循环体中使用null-宽恕操作符或附加条件。
发布于 2020-07-20 01:37:12
要回答有关读取器本身的空性的具体问题:reader
是一个StreamReader?
,因为NRT决定使用var
将变量的类型推断为可空。
参见此规范的章节:
可空隐式局部变量
var
为引用类型推断带注释的类型。例如,在var s = "";
中,var
被推断为string?
。
语言设计说明解释了这个决定。最后,他们得出结论:
使
var
具有一个可空注释类型,并推断流类型为正常类型。
因为var?
没有语法,所以该类型被推断为最不严格的类型(即,允许稍后将null
赋值给变量)。最终,应该通过流分析来跟踪空值。
也就是说,众所周知,使用OpenText
总是返回一个非null
对象(否则它会抛出),并且有一个不可空返回类型。要删除问题,只需将变量直接声明为StreamReader
StreamReader reader = File.OpenText(path);
正如其他答案所指出的,我认为你对实际的错误以及它在哪里发生感到困惑。只有在调用List<>.Add
时才会出现"item“。当然,这是因为StreamReader.ReadLine
可以返回null
,并且您的列表声明为List<string>
而不是List<string?>
。
你的选择是:
reader.ReadLine()!
(可能,但前提是保证)null
的检查(直接或通过修改循环条件来实现赋值和空检查)https://stackoverflow.com/questions/62988160
复制