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

Chr*_*hr. 3 .net c# visual-studio-2022

我在 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);
Run Code Online (Sandbox Code Playgroud)

并在 doc.SelectNodes 行收到“CS8602:取消引用可能为空的引用”。该代码的工作原理是,它不会失败,而是在找不到名为“aaa”的节点时不执行任何操作。如果我输入“root”,它就会找到它。因此,据我所知,我没有做错任何事,也没有冒犯编译器。

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

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

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

Fri*_*ied 7

如果您确实确定代码中可为 null 的值不能为 null,请使用 null-forgiving 运算符https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-forgiving。请参阅最小字符更改“!” 在代码中。

XmlDocument doc = new XmlDocument();
doc.LoadXml("<root/>");
foreach (XmlNode node in doc.SelectNodes("aaa")!)
  Console.WriteLine(node.OuterXml);
Run Code Online (Sandbox Code Playgroud)

确保 SelectNodes(...) 确实不会返回 NULL。对于您的示例来说似乎没问题 - 请参阅 https://source.dot.net/#System.Private.Xml/System/Xml/Dom/XmlNode.cs,9d1bb97e7daa3b4e,references


Nig*_*gel 6

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

是编译器警告逻辑中的错误吗?

有没有更好的(意思是,简短的,而不是多余的)方法来编写类似的代码?
“更好”是主观的。我认为你的代码很好,但这就是警告希望你做的事情:

 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);
Run Code Online (Sandbox Code Playgroud)

或者你可以这样做:

XmlDocument doc = new XmlDocument();
doc.LoadXml("<root/>");
foreach (var node in Enumerate(doc.SelectNodes("aaa")))
    Console.WriteLine(node.OuterXml);
Run Code Online (Sandbox Code Playgroud)
private static IEnumerable<XmlNode> Enumerate(XmlNodeList? list)
{
    if (list == null) yield break;
    foreach (XmlNode item in list)
    {
        yield return item;
    }
}
Run Code Online (Sandbox Code Playgroud)