標籤:style blog http color 使用 sp strong div on
一、背景:互連網行業,為了降低部署風險,往往會將程式拆分成很多項目,編譯成多個dll部署,這樣修改的時候,只需要部署修改過的dll即可。
二、問題:有一個函數,在很多個地方被使用:
public fun1(A a ,B b){ //代碼主體}
突然有一天,有的地方調用的時候需要加入一個參數C c,但是又不想其他客戶程式有任何變動,可以這樣改:
方法一:使用選擇性參數
public fun1(A a ,B b,C c = 1){ //代碼主體}
程式修改完後,在本地程式完美運行,將dll發測試。在測試環境,莫名其妙的報錯。由於系統分層處理,web網站和Web API分離,錯誤返回到最上層,已經看不到錯誤原因,查了老半天日誌,終於發現是另外一個dll調用了fun1函數,報找不到方法 fun1的錯誤。 將程式修改為:
方法二:重載
public fun1(A a ,B b){ fun1(A a ,B b,1);}public fun1(A a ,B b,C c){ //代碼主體}
重新發布dll,程式正常運行。
三、初步結論: 將代碼修改成選擇性參數,客戶程式需要重新編譯,不然客戶程式調用的時候會報找不到方法的錯誤。如果,客戶程式太多,為了避免部署所有客戶程式的dll,可以用方法二,重載的方法。
四、驗證:方法無預設參數: 方法有選擇性參數: 客戶程式Program編譯後的IL:
五、最終結論:由圖可知,客戶程式的c#源碼雖然沒有變,但是編譯後的IL中間代碼確改變了,調用的函數也傳了兩個參數,並把函數預設參數888在客戶程式聲明,使用。可以得出的結論是,C#選擇性參數函數其實是在編譯的時候,在函數調用的地方做了處理,把預設參數傳了進去。
六、現在問題來了,大家請思考微軟為什麼要這樣做呢?為什麼不在編譯的時候,像以下代碼一樣,做類似重載的處理呢? 這樣的話就不用重新編譯客戶程式了
public fun1(A a ,B b){ fun1(A a ,B b,1);}public fun1(A a ,B b,C c){ //代碼主體}
c#選擇性參數的一個陷阱