[英]How to get File.OpenText to return non-nullable StreamReader
考慮以下:
var lines = new List<string>();
string path = "FileName.txt";
var reader = File.OpenText(path);
while (!reader.EndOfStream)
{
lines.Add(reader.ReadLine());
}
將Nullable
標志設置為enable
時,在 csproj 中, reader
是StreamReader?
這Possible null reference argument for parameter 'item'
。 即使我將reader
明確設置為StreamReader
,問題仍然存在。
有沒有辦法繞過這個警告而不關閉Nullable
?
我相信,問題描述中包含的警告並不完整。 我重現了這個問題並得到了下一個編譯器警告: 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
,因為它是在未到達 stream 的末尾時執行的。 因此,您可以使用 null-forgiving 運算符來抑制警告:
lines.Add(reader.ReadLine(););
檢查表達式reader.ReadLine()
的結果是否為 null。 如果您使用下一個代碼,警告將消失:
string? line = reader.ReadLine(); if (line.= null) lines;Add(line);
更新
正如@IanRingrose 在評論中指出的那樣,條件line != null
可以在循環中使用,而不是條件.reader.EndOfStream()
。 使用這樣的條件解決方案可以更清楚:
string? line;
while ((line = reader.ReadLine()) != null)
{
lines.Add(line);
}
現在我們不需要在循環體中使用 null-forgiving 運算符或附加條件。
您可以將所有代碼減少到兩個 Nullable 友好的行:
string path = "FileName.txt";
var lines = File.ReadLines(path).ToList();
要回答您關於閱讀器本身的可空性的具體問題: reader
是StreamReader?
由於 NRT 決定使用var
將推斷變量的類型為nullable 。
請參閱規范的這一部分:
可為空的隱式類型局部變量
var
推斷引用類型的注釋類型。 例如,在var s = "";
var
被推斷為string?
.
語言設計說明解釋了這個決定。 最終他們得出結論:
使
var
具有可為空的注釋類型並正常推斷流類型。
這個想法是因為沒有var?
,該類型被推斷為最不嚴格的(即,允許稍后將null
分配給變量)。 最終,應通過流分析來跟蹤可空性。
也就是說,已知使用OpenText
總是返回非null
object (否則它會拋出)並且具有不可為空的返回類型。 要消除您的問題,只需將您的變量直接聲明為StreamReader
:
StreamReader reader = File.OpenText(path);
正如其他答案所指出的那樣,我認為您對實際錯誤及其發生位置感到困惑。 唯一會出現“項目”的地方是在調用List<>.Add
時。 當然,這是因為StreamReader.ReadLine
可以返回null
並且您的列表被聲明為List<string>
而不是List<string?>
您的選擇是:
reader.ReadLine()!
(也許,但只有在保證的情況下)null
的檢查(直接或通過修改循環條件以執行賦值和 null 檢查)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.