2014-02-21 26 views
1

我想寫一個輔助方法,它需要一個func和第二個參數T,並嘗試調用它。如果發生Null引用異常,則返回T(第二個參數)。如果成功,返回通過FUNC的結果,而不是這樣的:傳遞函數,可能是一個空引用異常作爲參數

tableRow[rowNum, fieldNamePos].Value != null ? tableRow[rowNum, fieldNamePos].Value.ToString() : ""; 

我可以寫

Helper.GetDefaultIfNull(tableRow[rowNum, fieldNamePos].Value.ToString,"") 

我相信這是更簡潔,更少的代碼。下面是我在GetDefaultIfNull方法:

public T GetDefaultIfNull<T>(Func<T> funcToInvoke, T defaultValue) 
{ 
    T result; 
    try 
    { 
     result = stringFunc.Invoke(); 
    } 
    catch (NullReferenceException) 
    { 
     result = defaultValue; 
    } 

    return result; 
} 

當我運行測試,這在非空引用傳遞時,卻傳遞一個空引用時正常工作,它拋出調用的方法,因此,當一個錯誤似乎在將它傳遞給方法時調用該函數?這裏是測試代碼:

[TestMethod] 
    public void NULL_EXCEPTION_return_default() 
    { 
     StringBuilder sb = null; 

     //Func<string> stringFunc = ; 
     var defaultValue = ""; 
     var result = new Helper().GetDefaultIfNull(sb.ToString, defaultValue); 

     Assert.AreEqual(defaultValue, result); 
    } 

有沒有辦法做到這一點?

+1

你知道[''''操作符](http://msdn.microsoft.com/en-us/library/ms173224.aspx)嗎?如果我明白了,它基本上就是做你想達到的。 – aloisdg

+0

是這樣嗎?(例外) { return T; }' 如果這就是你的意思,那麼每次我這樣做的時候就是8行代碼。 – MickJuice

+1

我知道嗎?但是這涉及到一個調用這個對象的方法。我需要確保它在調用該對象的方法之前不爲null – MickJuice

回答

3

發生這種情況是因爲通過以這種方式訪問​​某個對象的方法,您正在仍然取消引用空指針。換句話說,這一行:

sb.ToString 

試圖訪問一個空引用(sb)的成員(ToString)。

改變你調用你的函數將解決問題的方式:

var result = new Helper().GetDefaultIfNull(() => sb.ToString(), defaultValue); 

也就是說,創建一個新的Lambda和調用該網址。您期望在您的方法中使用的NullReferenceException將以您期望的方式拋出,捕捉並處理。

+0

是的!尼斯。這工作。謝謝! – MickJuice

0

嘗試查找函數時發生空引用,即如果sb爲空,則sb.ToString將引發NullReferenceException。我建議你可能要像做

public T GetDefaultIfNull<T>(object value, T defaultValue) 
{ 
    return value == null 
      ? defaultValue 
      : Convert.ChangeType(value, typeof(T)); 
} 

然後把它作爲

Helper.GetDefaultIfNull(tableRow[rowNum, fieldNamePos].Value, ""); 

現在,這種假設值轉換爲T但我假設你知道什麼類型的它應該是和轉換操作要麼是無操作,要麼你會知道它會起作用。

0

試試這個:

public T GetDefaultIfNull<T>(Func<T> funcToInvoke, T defaultValue) 
{ 
    T result; 
    try 
    { 
     result = stringFunc.Invoke(); 
     if (result == null) 
     { 
      //Do something with result as it is not null 
     } 
     else{ 
      result = defaultValue; 
     } 
    } 
    catch (Exception ex) 
    { 
     ex.Message; 
    } 

    return result; 
} 
0

您也可以在您做一個簡單的完整性檢查

public T GetDefaultIfNull<T>(Func<T> funcToInvoke, T defaultValue) { 
    T result; 
    if (funcToInvoke == null) { 
     return result = defaultValue; 
    } 
    try { 
     result = funcToInvoke.Invoke(); 
    } catch (Exception) { 
     result = defaultValue; 
    } 

    return result; 
} 

而且測試方法低於替代。

//running a NUnit test 
[Test] 
public void NULL_EXCEPTION_return_default() { 
    StringBuilder sb = null; 
    var defaultValue = string.Empty; 
    var result = new TestHelper().GetDefaultIfNull(sb.ToString, defaultValue); 

    Assert.AreEqual(defaultValue, result); 
} 
相關問題