读取 XML 时在 LINQ 中正确使用空条件运算符
Correct use of null-conditional operator in LINQ while reading XML
我正在使用 XML 序列化器解析以下 XML 文件。
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Projects>
<Global>
<Variables>
<Variable name="GlobalVar1" value="GV1"/>
<Variable name="GlobalVar2" value="GV2"/>
</Variables>
</Global>
<Project>
<Variables>
<Variable name="LocalVar1" value="LV1"/>
<Variable name="LocalVar2" value="LV2"/>
</Variables>
</Project>
</Projects>
我正在构建一个变量字典 - 名称-值对。我写了以下工作正常的 LINQ 语句(假设我在全局和项目范围内没有重复的变量名):
Dictionary<String, String> varDict = Projects.Global.Variables.Select(var => new { var.name, var.value })
.Union(Projects.Project.Variables?.Select(var => new { var.name, var.value }))
.ToDictionary(var => var.Key, var => var.value);
现在我遇到了一个问题 - 有时整个 <Global>
标签都会丢失,或者它没有 <Variables>
标签。同样,有时 <Variables>
标签会从 <Project>
标签中丢失。例如:XML 文件将是:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Projects>
<Project>
<Variables>
<Variable name="LocalVar1" value="LV1"/>
<Variable name="LocalVar2" value="LV2"/>
</Variables>
</Project>
</Projects>
我认为如下使用 ?.
运算符(空条件)会有所帮助,但是当 <Global>
标记缺少以下 LINQ 语句时 returns null
(varDict
是 null
):
Dictionary<String, String> varDict = Projects.Global?.Variables?.Select(var => new { var.name, var.value })
.Union(Projects.Project.Variables?.Select(var => new { var.name, var.value }))
.ToDictionary(var => var.Key, var => var.value);
我做错了什么或者解决方法是什么?
?.
运算符只是避免抛出 NullReferenceException。它仍然 returns 无效。
// If Projects.Global is null:
var var1 = Projects.Global?.Variables; // Does not throw an exception, but var1 is null
var var2 = Projects.Global.Variables; // Blows up and throws a NullReferenceException
如果您希望 .Union()
在第一部分为空时工作,则需要一些东西来解决。所以类似的东西应该可以工作(可能需要一些调整):
var globalValues = Projects.Global?.Variables?.Select(var => new KeyValuePair<string, string>(var.name, var.value))
?? new List<KeyValuePair<string, string>>();
Dictionary<String, String> varDict = globalValues
.Union(Projects.Project.Variables?.Select(var => new KeyValuePair<string, string>(var.name, var.value)))
.ToDictionary(var => var.Key, var => var.Value);
我正在使用 XML 序列化器解析以下 XML 文件。
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Projects>
<Global>
<Variables>
<Variable name="GlobalVar1" value="GV1"/>
<Variable name="GlobalVar2" value="GV2"/>
</Variables>
</Global>
<Project>
<Variables>
<Variable name="LocalVar1" value="LV1"/>
<Variable name="LocalVar2" value="LV2"/>
</Variables>
</Project>
</Projects>
我正在构建一个变量字典 - 名称-值对。我写了以下工作正常的 LINQ 语句(假设我在全局和项目范围内没有重复的变量名):
Dictionary<String, String> varDict = Projects.Global.Variables.Select(var => new { var.name, var.value })
.Union(Projects.Project.Variables?.Select(var => new { var.name, var.value }))
.ToDictionary(var => var.Key, var => var.value);
现在我遇到了一个问题 - 有时整个 <Global>
标签都会丢失,或者它没有 <Variables>
标签。同样,有时 <Variables>
标签会从 <Project>
标签中丢失。例如:XML 文件将是:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Projects>
<Project>
<Variables>
<Variable name="LocalVar1" value="LV1"/>
<Variable name="LocalVar2" value="LV2"/>
</Variables>
</Project>
</Projects>
我认为如下使用 ?.
运算符(空条件)会有所帮助,但是当 <Global>
标记缺少以下 LINQ 语句时 returns null
(varDict
是 null
):
Dictionary<String, String> varDict = Projects.Global?.Variables?.Select(var => new { var.name, var.value })
.Union(Projects.Project.Variables?.Select(var => new { var.name, var.value }))
.ToDictionary(var => var.Key, var => var.value);
我做错了什么或者解决方法是什么?
?.
运算符只是避免抛出 NullReferenceException。它仍然 returns 无效。
// If Projects.Global is null:
var var1 = Projects.Global?.Variables; // Does not throw an exception, but var1 is null
var var2 = Projects.Global.Variables; // Blows up and throws a NullReferenceException
如果您希望 .Union()
在第一部分为空时工作,则需要一些东西来解决。所以类似的东西应该可以工作(可能需要一些调整):
var globalValues = Projects.Global?.Variables?.Select(var => new KeyValuePair<string, string>(var.name, var.value))
?? new List<KeyValuePair<string, string>>();
Dictionary<String, String> varDict = globalValues
.Union(Projects.Project.Variables?.Select(var => new KeyValuePair<string, string>(var.name, var.value)))
.ToDictionary(var => var.Key, var => var.Value);