温柔的枚举陷阱

     去年上线的一个项目,却在最近出现了个比较头疼的问题。先说明一下,该系统是个业务管理系统,

大概会处理上百个业务,每处理完一个业务,都要给客户发一封确认信或者说明信,信的内容是通过读取模板加替换参数方式做成的,

模板是文本文件,当要读取一个模板的内容时,先判断内存中是否有该模板,如果有就直接从内存中读取,

如果没有则从文件读入并放入到内存中,内存中是放到Hashtable中的,key为枚举类型,也就是为每一种

模板定义了一个枚举值。问题就出在模板内容这里,明明是办理的A业务,

结果却给客户发的是关于B业务的相关说明。为什么说头疼呢,因为这个错误只在最终客户

那里出现过,在组内及中间客户的环境中均不能再现,而且再最终客户处也是时隐时现。

  

     ……经过数日的调查也未见所以然啊,最后迫不得已从最终客户处要来了相关的dll文件和log才发现了

问题的所在。原来,通过查看IL代码发现很多引用的枚举值都变了,比如代码中引用的是A类型的信,结果在IL代码中

却变成了B类型。究其原因,大家都知道枚举值就是个整数,代码编译后,DLL中只保留该枚举的整数值,

而如果枚举本身有变化的话,比如在中间加入了一项值,那么该项后面枚举的值都会改变的(如果不是显示指定值的话)

。这个时候如果只重新编译了枚举本身,而没有编译各个引用枚举的地方的话,那么就会出现张冠李戴的问题。我们的

问题就出在这里,当时为了对应一个bug在枚举中间加了一个值,而只编译了与这个bug有关的工程,其他的引用的地方

都没有编译,所以才……

     

      虽然调查这个问题花了不少时间,但是感觉还是挺值的,知道了枚举的这个问题,希望大家以后用枚举的时候注意这个问题。

      说起来出现这个问题也是挺不容易的,

      如果不是把模板文件保存到内存中而是每次都重新读取……     

      如果不是使用枚举来标识信件……

      如果不是使用默认的枚举值(没有显示指定枚举值)……

      如果不是在枚举的中间插入了新值(而不是在最后)……

      如果不是把项目做成了很多project(使得定义枚举和使用枚举在不同的编译单元中)……

      如果以前有过类似的经验或者看过这样的帖子(呵呵)……

posted @ 2010-06-01 11:33  刘鸿海  阅读(4094)  评论(32编辑  收藏  举报