现象
最近在工作中遇到了一次奇怪的编译出错。事情是这样的,本来这个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(假的实现)。等那位专人解决这个问题之后再进行合起来的编译。