我试图从XmlDocument中解析XML属性。由于可能,某个节点没有特定的属性,我创建了一个扩展方法来检查属性,如果属性为null或无效,则返回默认值:
public static bool TryParseOrDefault(this string toParse, bool defaultValue)
{
if(toParse == null) return defaultValue;
bool result;
if(Boolean.TryParse(toParse, out result))
{
return result;
}
return defaultValue;
}
这种方法效果很好,但是当我想要检查的对象为空时它不会出现:
var whatever = column.Attributes["SomeAttribute"].Value.TryParseOrDefault(true);
在这种情况下,column
节点没有SomeAttribute
属性,因此Value
为空并且抛出NullReferenceException
。这是为什么?我认为扩展方法应该适用于null对象,因为调用基本上转换为:
MyExtensions.TryParseOrDefault(column.Attributes["SomeAttribute"].Value,true);
答案 0 :(得分:4)
.Value
null
不是null.Value
,但是您正在有效地执行此属性XAttribute
,这会引发上述异常。您可以更改扩展方法以接受public static bool TryParseOrDefault(this XAttribute toParse, bool defaultValue)
{
if(toParse == null) return defaultValue;
bool result;
if(Boolean.TryParse(toParse.Value, out result))
{
return result;
}
return defaultValue;
}
而不是字符串
var whatever = column.Attributes["SomeAttribute"].TryParseOrDefault(true);
然后像这样调用它
public static bool Attribute(this XElement elem, string attributeName, bool defaultValue)
{
var toParse = (string)elem.Attribute(attributeName);
bool result;
if(Boolean.TryParse(toParse, out result))
{
return result;
}
return defaultValue;
}
您还可以创建LINQ2XML扩展方法的覆盖
var whatever = column.Attribute("SomeAttribute",true);
然后你会像这样使用:
{{1}}
答案 1 :(得分:3)
我怀疑问题是如果Attributes["SomeAttribute"]
返回null - 那么找到Value
属性将失败。如果column
是XmlElement
,肯定会出现这种情况 - 请查看XmlAttributeCollection.ItemOf(string)
property (the indexer):
物业价值
具有指定名称的XmlAttribute。如果该属性不存在,则此属性返回null。
您对扩展方法的翻译是正确的 - 但我不认为这是问题所在。虽然很容易测试 - 只需将语句拆分出来用于诊断目的:
string tmp = column.Attributes["SomeAttribute"].Value;
var whatever = tmp.TryParseOrDefault(true);
我怀疑您会在第一个行找到异常,而不是第二行。
您可能希望考虑使用LINQ to XML,这样可以更容易 - 您可以使用:
string tmp = (string) column.Attribute("SomeAttribute");
如果属性丢失, 将返回null
,因为从XAttribute
到string
的显式转换将返回null
"源"转换是空引用。
(如果仅需要XmlAttribute
,那么符文的答案也很棒。这取决于你想要做什么。)