2010-07-14 85 views
1

我在公開方法中公開了一個關於repeated parameter-checks的問題。參數檢查方法

這個結果在我看來很清楚,但是出於這個原因,我還有另外一個關於這些參數檢查的問題(我在回答最後一個問題時腦子裏有同樣的問題,但是表達方式太尷尬了,一個職位),我希望這一次是更好):


如果我已經重複將給予一類礦井的公共方法參數,這些參數必須在每個公共方法進行驗證。如果我委託檢查到另一個(私有)的方法,如

void EnsureIndexIsValid(int index){ 
    if(index <0 || index > A_VALUE){ 
     throw new IndexOutOfRangeException(「..message..」); 
    } 
} 

然後投擲方法EnsureIndexIsValidIndex而不是調用的方法。這是不好的做法嗎?

如果不好的做法,一種可能性是在使用方法中捕獲異常,然後重新拋出異常。這是不錯的做法(調用者的例外來源現在是AMethod,而不是EnsureIndexIsValid)?還是隻是開銷?

public void AMethod(int index,....){ 
    try{ 
     EnsureIndexIsValid(index) 
    }catch(IndexOutOfRangeException e){ 
     throw e; 
    } 
    // .... 

編輯: 以下似乎definitivey不是一個好主意

如果這將是很好的做法,這將是合法趕上一般例外更多的這些檢查,然後再-throw:

public void AMethod(int index,....){ 
    try{ 
     EnsureIndexIsValid(index); 
     EnsuresValueIsInValidRange(anotherParamter); 
    }catch(Exception e){ 
     throw e; 
    } 
    // ... 

結論:

對於所有來到這個線程,這裏簡短的回答:

參數檢查委派似乎是一種常見的模式,是合理的。但是重新拋出這種例外來隱藏驗證方法並不聰明。最好從驗證方法返回一個布爾值,如果檢查失敗,則在公共方法中拋出異常。

回答

2

我寧願有私有方法是bool IndexIsValid,則實際public方法看起來像

if(!IndexIsValid(parameterToThisMethod)) 
{ 
    throw new ArgumentOutOfRangeException("parametersToThisMethod"); 
} 

這具有在調用堆棧頂部的實際方法的優勢。

而且,即使你做它的其他方式(與私營驗證方法投擲),這種模式:

catch(IndexOutOfRangeException e) 
{ 
    throw e; 
} 

沒有做好事的調用堆棧在所有;簡單throw;throw new IndexOutOfRangeException("parameter", e);

1

你不應該捕獲Exception,只是你可以處理的那些,所以你不應該使用你的最後一個例子。

+0

我知道,捕捉異常不是很好(如果我問良好的做法,我認爲它的雙倍壞),但我認爲,在只有參數驗證完成的情況下,它不會那麼邪惡。如果發生stackoverflow異常,catch不會被捕獲,其他異常不太可能,但是你是對的,它肯定不是很好。所以擴展不是一個好主意。但是關於重新拋出異常的主要問題怎麼樣 – HCL 2010-07-14 12:18:14

+0

@happyclicker - 編輯是個好主意。就我個人而言,我不喜歡重新拋出異常。您可以隨時查看調用堆棧以查看哪種方法稱爲驗證代碼。 – ChrisF 2010-07-14 12:36:16

1

不,我認爲將驗證委託給另一種方法並不是一種錯誤的做法,我不會重複拋出高級方法中的例外來給出這種印象。客戶端並不關心異常來自何處,只是爲什麼它被拋出。

2

我想說在驗證方法中拋出異常是一種很好的做法,因爲這是發生問題的位置(驗證失敗)。如果您需要知道誰調用了驗證方法,那麼異常將在其調用堆棧中提供該信息。所以我會而不是捕獲並重新拋出驗證異常。

HTH。