2010-07-14 79 views
5

我經常擁有調用層次結構,因爲所有方法都需要相同的參數。如果我不想將它們放在實例級別(類的成員),那麼我總是問我是否有意義在每種方法中檢查它們的有效性。函數中的重複參數檢查

例如:

public void MethodA(object o){ 
    if(null == o){ 
     throw new ArgumentNullException("o"); 
    } 
    // Do some thing unrelated to o 

    MethodB(o); 

    // Do some thing unrelated to o 

} 

public void MethodB(object o){ 
    if(null == o){ 
     throw new ArgumentNullException("o"); 
    } 
    // Do something with o 
} 

如果Method A使用的參數,那麼它的清晰,我必須有,並檢查有效性MethdoB。但是,只要MethodA沒有更多地使用o而不是MethodB,在MethodA中檢查有效性也是一種好的做法。

MethodA也檢查的優勢可能是異常拋出被調用者調用的方法,這很好,但它是否有必要?調用堆棧也會說明這一點。也許它的意義在公共,內部,受保護但不是私人方法?

我以空檢查爲例,但索引驗證或範圍驗證屬於自我問題,但我認爲由於冗餘代碼的危險而存在限制。你怎麼看?

UPDATE

通過我已經看到了,我是有點精確AakashM的答案。 MethodA不僅呼叫MethodB,它也做其他事情,但不涉及o。我添加了一個例子來澄清這一點。謝謝AakashM。

回答

9

史蒂夫麥康奈爾的代碼完整談論'路障'的概念 - 一個防禦牆外的數據是不可信的,內部的數據是值得信賴的。想要進入路障的數據必須經過驗證過程,但是在路障中,數據可以隨意通過驗證碼自由移動。

如果你可以在你的項目中加入這樣的構造和分層,並且堅持下去,它確實會使內部代碼的代碼更少,更精髓。但是隻需要一種方法就可以調用路障來防止出錯。

在你的例子中,MethodBpublic。這意味着你沒有自動的未來保證MethodA將成爲它的唯一調用者 - 因此我會說它的驗證碼應該保留。但是,如果它是private,那麼您可以爲刪除它做一個參數。

至於MethodA,如果它實際上沒有沒有多於致電MethodB,它應該不存在。如果它是未來擴展的存根,並且在某些時候它將與o做些什麼,那麼它的驗證代碼也應該保留。

1

我認爲你應該確保它一旦產生輸入值(調用者的責任)。如果該類僅由內部客戶端使用,這將起作用。如果它是公共API的一部分,那麼您不能退出支票,但您可能需要將它們分解,正如其他答案中所述。

出於測試目的,您也可以在兩種方法中使用Debug.Assert(o != null),如果性能問題,檢查將從發佈代碼中刪除。

+0

產生輸入值的地方 - 在調用者意味着什麼?我想要寫我的例子的例子是,方法A和B都可以從類的外部訪問,並且它的合法調用其中的一個(MethodA執行相同,比MethodB稍微多一點) – HCL 2010-07-14 11:01:53

+0

是的。看我的編輯。 – Mau 2010-07-14 11:21:16

1

我不認爲參數驗證「冗餘代碼」。您需要保護所有外部入口點。如果你有一個private的方法,這樣你就知道時間流程到了它的所有參數都會有效,那麼你可能有一個例子,但是對於public(甚至protected)方法你真的不會。