2010-03-16 68 views
3

我有如下代碼:檢查空引用

searchResults.SearchResultCollection.Add(
       new SearchResult() 
        { 
         Header = 
         HttpUtility.HtmlDecode(
         htmlDocument.DocumentNode 
         .SelectSingleNode(initialXPath + "h3") 
         .InnerText), 
         Link = HttpUtility.HtmlDecode(
         htmlDocument.DocumentNode 
         .SelectSingleNode(initialXPath + "div/cite") 
         .InnerText) 
        } 
       ); 

有時htmlDocument.DocumentNode.SelectSingleNode(....)返回null,我的應用程序使用的NullReferenceException崩潰。當然,我可以編寫檢查空引用返回值的代碼,但代碼將過於冗長。什麼是優雅的方式來做到這一點?

+0

解決它,你建議的方式。它會有更易於閱讀的好處! – 2010-03-16 01:09:59

+0

當你的XPATH沒有找到任何東西時,你也必須決定它的意思(這就是爲什麼返回null)。如果存在空值,你想要做什麼?將SearchResult的'Header'和'Link'屬性保留爲'null'? – 2010-03-16 01:14:11

回答

3

您可以在XmlNode的創建擴展方法,比如:個人

public static class ExtensionMethods 
{ 
    public string GetNodeText(this XmlNode node, string xPath) 
    { 
     var childNode = node.SelectSingleNode(xPath); 
     return (childNode == null) 
      ? "" : childNode.InnerText; 
    } 
} 

searchResults.SearchResultCollection.Add(
    new SearchResult() 
     { 
      Header = HttpUtility.HtmlDecode(
        htmlDocument.DocumentNode.GetNodeText(initialXPath + "h3"), 
      Link = HttpUtility.HtmlDecode(
        htmlDocument.DocumentNode.GetNodeText(initialXPath + "div/cite") 
     } 
    ); 

,我可能只是把它吸上來,放在explicityly空測試,雖然:)

1

我看不到如何檢查null過於冗長。如果你在任何地方都做同樣的事情(拉出一個節點)。您可以將其抽象爲執行空檢查的單個方法/函數。這樣,在你試圖抓取一個節點的地方,你不會有空檢查,因爲空檢查整齊地封裝在函數/方法中。我想你將不得不執行顯式的空檢查。可能還有其他方法可以做到,但要小心。雅緻,聰明和駭人之間有一條細線。 ;)

+0

在他的例子中,它遺失了流暢的界面 – 2010-03-16 01:18:25

+0

Gotcha。我從更一般的角度來看待它。 – 2010-03-16 01:20:59

+0

是的,我的意思是說,你和其他評論者在抽象它的時候碰到了頭,但我認爲這是他最初的擔憂。 – 2010-03-16 01:32:56

3

創建SelectSingleNode的Try版本作爲擴展方法。

public static class XmlNodeExtensions 
{ 
    public static bool TrySelectSingleNode(this XmlNode node, 
              string xpath, 
              out XmlNode result) 
    { 
     result = node.SelectSingleNode(xpath); 
     return (result != null); 
    } 
} 

你會那麼你的代碼更改爲:

XmlNode node; 
searchResults.SearchResultCollection.Add(
    new SearchResult 
    { 
     Header = HttpUtility.HtmlDecode(
      htmlDocument.DocumentNode 
       .TrySelectSingleNode(initialXPath + "h3", out node) 
        ? node.InnerText 
        : null), 
     Link = HttpUtility.HtmlDecode(
      htmlDocument.DocumentNode 
       .TrySelectSingleNode(initialXPath + "div/cite", out node) 
        ? node.InnerText 
        : null) 
    }); 
2

只要寫一個擴展方法。

public static class Extensions 
{ 
    public static String SafeInnerText(this XmlElement node, String default) 
    { 
     return (node != null) ? node.InnerText : default; 
    } 
} 

然後按如下方式使用它。

[...].SelectSingleNode(initialXPath + "h3").SafeInnerText("NoInnerText"); 

是的,我知道,default是保留關鍵字...