无法使用null-object调用扩展方法

时间:2014-05-20 06:09:07

标签: c# extension-methods

我试图从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);

2 个答案:

答案 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属性将失败。如果columnXmlElement,肯定会出现这种情况 - 请查看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,因为从XAttributestring的显式转换将返回null "源"转换是空引用。

(如果需要XmlAttribute,那么符文的答案也很棒。这取决于你想要做什么。)