我在 VS 2022、C# .NET 6.0 中有以下示例代码:
using System.Xml;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root/>");
foreach (XmlNode node in doc.SelectNodes("aaa"))
Console.WriteLine(node.OuterXml);
并且在 doc.SelectNodes 行收到“CS8602:取消引用可能为空的引用”。该代码的工作原理是,它不会失败,而是在找不到名为“aaa”的节点时不执行任何操作。如果我输入“root”,它就会找到它。所以,据我所知,我没有做错任何事,也没有冒犯编译器。
然而,警告确实存在,而且似乎是错误的,因此很烦人。我的两个问题是:
我发现我可以添加“#pragma warning禁用CS8602”,但这感觉不是一个很好的解决方案。理想情况下,我想在其他情况下利用此警告,这些情况在我看来是合法的,与此不同。
如果您确实确定代码中可为 null 的值不能为 null,请使用 null-forgiving 运算符 https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null -宽容。请参阅最小字符更改“!”在代码中。
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root/>");
foreach (XmlNode node in doc.SelectNodes("aaa")!)
Console.WriteLine(node.OuterXml);
确保 SelectNodes(...) 确实不会返回 NULL。对于你的例子来说似乎没问题 - 请参阅 https://source.dot.net/#System.Private.Xml/System/Xml/Dom/XmlNode.cs,9d1bb97e7daa3b4e,参考文献
停止出现错误的最优雅的方法是什么?
在您的项目文件中删除
<Nullable>enable</Nullable>
是编译器警告逻辑的bug吗?
不
有没有更好的(意思是,简短的,不是多余的)方法来编写类似的代码?
“更好”是主观的。我认为你的代码很好,但这就是警告希望你做的事情:
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root/>");
var nodes = doc.SelectNodes("aaa");
if (nodes == null)
{
//handle this case here
return;
}
foreach (XmlNode node in nodes)
Console.WriteLine(node.OuterXml);
我现在明白,正如 GSerg 所评论的那样,声明为 XmlNodeList?(string) 的 API 方法是警告的来源(但是,它永远不会返回 null;它返回对空列表的非空引用)。
到目前为止我发现的主观“最优雅”的解决方案是这样做:
#pragma warning disable CS8602
foreach (XmlElement item in doc.SelectNodes("..."))
#pragma warning restore CS8602
因为这仅仅抑制了这个实例,而且我可以从这个警告的其他实例中受益,我敢说,这些实例更合法。