現象
最近在工作中遇到了一次奇怪的編譯出錯。事情是這樣的,本來這個asp.net webform應用是可以編譯的。但是將另外一個class library的工程加入到這個asp.net webform應用的引用中,還未改任何其它的代碼。這個asp.net webform應用就出現了編譯錯誤。分析這些編譯出錯的地方,再看了SVN歷史,這些文件最近都沒有改過(最近一次改動是六月的事情了),但是這些文件確實是編譯有錯。有點奇怪。一時想不出來為什么。等到第二天,繼續分析,突然發現引起編譯出錯的類型是屬於這個新加入引用的工程。看了編譯出錯的代碼,其並沒有引入任何新加入引用的工程任何名稱空間。這就奇怪了。還沒有引入其任何名稱空間,只是把引用剛加上就出了編譯出錯。這個asp.net webform工程原來是可以編譯的,為什么會加入一個引用后就不能編譯了呢?會不會去掉引用還是能編譯?於是試着去掉了這個新加的引用。編譯。果然可以編譯。之前出錯的地方不再出錯了。看了一下那些之前出錯的類型,發現居然是另外一些在本來asp.net webform工程里的一些類,並不是新加工程里的類。而且這些類都有名稱空間。這就奇怪了,為什么加入引用之后,這些類就變成了新加工程里的類呢?打開了新加工程里的類,仔細看了一下,發現了一個問題,即該類沒有定義名稱空間,同時該類的名字與asp.net webform工程里的類同名。這就是為什么這些沒有名稱空間的類會引起編譯錯誤的原因了。當.net compiler定位一個類時,如果有兩個類同名,一個類有名稱空間,另一個沒有。.net compiler優先搜索沒有名稱空間的類,然后再去搜索有名稱空間的類。原來的程序引用的是有名稱空間的類,沒有加入新引用時一切都沒有問題。當加入引用時,而且新的類沒有名稱空間,剛好可以把原來的有名稱空間的類替換掉。.net compiler優先搜索到這個沒有名稱空間的類,從而引起原來的程序出錯。因為原來有名稱空間的類已經變了,換成這個沒有名稱空間的類。既然找到了原因,那么解決辦法就簡單了。
解決方案
原因已經清楚了。解決辦法包括:
1. 給那些沒有名稱空間的類加上名稱空間
這個在實際情況中無法做到,這個新工程是由專人負責的。不能去改。
2. 給現有代碼強行加上全名稱空間+類名的引用方式
這種辦法技術上是可行,但是會引起代碼看起來很恐怖。也不打算采用。
3. 實際的解決方式:
給那位專人指出這個問題,然后去掉對新工程的引用。因為其引起已有工程編譯出錯。然后在已有工程里照搬了新工程里幾個類,寫了一些Mock up(假的實現)。等那位專人解決這個問題之后再進行合起來的編譯。