2009-08-30 21 views
4

我在一個方法中執行一些參數驗證並在必要時拋出異常。我是否需要手動拋出這種類型的異常?只要調用者被包裝在try..catch塊中,不管手動檢查是否到位,都會拋出類似的異常。我應該打擾從這個方法拋出一個異常嗎?

public static Int16 ToInt16(this byte[] value, int startIndex, bool isBigEndian) { 

     // are these exceptions necessary? 
     if (value == null) { 
      throw new ArgumentNullException("value"); 
     } 

     if ((startIndex + 1) >= value.Length) { 
      throw new ArgumentOutOfRangeException("startIndex"); 
     }  

     return (isBigEndian) 
      ? (Int16)((value[startIndex] << 8) | value[startIndex + 1]) 
      : (Int16)((value[startIndex + 1] << 8) | value[startIndex]); 
    } 

這是用於在陣列轉換2個字節到Int16的一種方式來切換大端或小字節序變換的擴展方法。

+0

請注意,您正在使用ParamName創建兩個例外,請嘗試考慮一條有用的消息。 – 2009-08-30 08:51:01

+0

全部,感謝您的評論。似乎一致認爲例外應該保留。我先接受了彼得的回答,他先找到了我的錯字,然後找到了我的錯字。 – user158485 2009-08-30 20:30:24

回答

9

在這裏拋出異常的值是,而不是得到一個空deref異常,你會得到一個參數異常,最重要的是告訴你這個參數是無效的。異常也更明確地指向原因,而不是一般的空的deref,它可以是任何東西。

鑑於這是一種擴展方法,它已經是一種間接的方式,我認爲它可能更加有用,包括例外。特別是鑑於你顯然已經寫了它,但即使是作爲一個政策的問題。如果這不是一種擴展方法,我可以採取任何方式。取決於代碼的隱藏程度,我可能也會使用assert。

我目前還不知道,但在.Net 1.1和1.0框架中,JIT編譯器不會內聯一個有投入的調用。爲了避免這種情況,通常意味着要創建一個不同的方法來引發異常。

順便說一句,你有一個錯誤與startIndex + 1> value.Length;它應該是> =代替。

3

如果你看看DotNET Framework代碼(比如使用Reflector),那麼你會發現MS人員會手動拋出這些異常。

如果您製作的SDK將被第三方程序員大量使用,我建議您至少在頂級函數上拋出ArgumentNullExceptions。

3

我的觀點是,你應該拋出一個異常。我的想法是,您似乎正在構建可重用的代碼,可能成爲其他程序或此程序其他部分中使用的庫的一部分。雖然您可能正在使用當前代碼中的適當異常處理,但不保證您或將來使用此方法的其他人將執行適當的異常處理。另一個考慮是在維護中,這種方法的實施可能會發生變化,您必須考慮不會立即引發問題並拋出異常的含義。我認爲你上面的代碼是可以的,除了我通常會提供一個更明確的信息來更明確一些(當然這是我的偏好,你正在做什麼仍然會傳達這個問題)。

3

任何你正在寫一個公共方法的時候,你應該把它像一個黑盒子,因爲其他程序員。

如果你有兩個方法,治法(int i)以方法b(int i)以,這是容易理解?

  • 治法(1000)拋出ArgumentOutOfRangeException
  • 方法b(1000)拋出IndexOutOfRangeException

方法a更容易固定,而不必打開代碼的方法。 方法B可能因爲與參數無關的原因而引發該異常,所以您必須調試該方法以確定發生了什麼問題。

+0

這種想法的一個問題是'ArgumentOutOfRangeException'也可能由'MethodA'調用的方法拋出,原因與傳遞給'methodA'的參數無關,'IndexOutOfRangeException'更能描述實際問題。真正需要的是區分與滲透方法無關的滲透的例外,但沒有標準的約定。 – supercat 2014-05-03 02:37:09

相關問題