在 VS2022、.NET 6、C# 10 中停止获取 CS8602 的最优雅方法

问题描述 投票:0回答:3

我在 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”,它就会找到它。所以,据我所知,我没有做错任何事,也没有冒犯编译器。

然而,警告确实存在,而且似乎是错误的,因此很烦人。我的两个问题是:

  1. 是不是编译器警告逻辑有bug?
  2. 有没有更好的(意思是,简短的,不是多余的)方法来编写类似的代码来搜索与某个 XML 查询匹配的所有节点并处理它们而不生成警告?

我发现我可以添加“#pragma warning禁用CS8602”,但这感觉不是一个很好的解决方案。理想情况下,我想在其他情况下利用此警告,这些情况在我看来是合法的,与此不同。

c# .net visual-studio-2022
3个回答
8
投票

如果您确实确定代码中可为 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,参考文献


7
投票

停止出现错误的最优雅的方法是什么?
在您的项目文件中删除

<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);

0
投票

我现在明白,正如 GSerg 所评论的那样,声明为 XmlNodeList?(string) 的 API 方法是警告的来源(但是,它永远不会返回 null;它返回对空列表的非空引用)。

到目前为止我发现的主观“最优雅”的解决方案是这样做:

#pragma warning disable CS8602
foreach (XmlElement item in doc.SelectNodes("..."))
#pragma warning restore CS8602

因为这仅仅抑制了这个实例,而且我可以从这个警告的其他实例中受益,我敢说,这些实例更合法。

© www.soinside.com 2019 - 2024. All rights reserved.