如果{} else {if {} else {if {…}}}“c# – 清理病态嵌套”

前端之家收集整理的这篇文章主要介绍了如果{} else {if {} else {if {…}}}“c# – 清理病态嵌套”前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我目前有不幸在Somebody Else的C#代码工作,这真的吹了我一下.我不知道我之前的人如何维护这个代码,因为它的各种病症已经崩溃了IDE,编译器,运行时环境…

我今天面临的问题涉及到一个15兆字节的源文件,具有真正令人头脑的病态嵌套程度.代码如下:

  1. if(var == 0) {
  2. // do stuff
  3. }
  4. else {
  5. if(var == 1) {
  6. // do stuff
  7. }
  8. else {
  9. if(var == 2) {
  10. // do stuff,identical word for word to the `var == 1` case
  11. }
  12. else {
  13. // etc.
  14. }
  15. }
  16. }

这是最好的时代的一个有问题的风格选择.然而,这与代码的另一个病理学结合在一起:这些块中的一些几乎几千级. (最深的是我打算测量超过700.)我真诚地希望在我之前的人作为他们的最后一个行为之一,然后被强制与这个守则分开,运行了一个造型工具,导致了我可憎的事情.我不能设想他们现在可能已经编写了这个代码,特别是因为代码的第三或第四个编辑会崩溃IDE. (有时会删除我的源文件副本,作为奖金.)

我写了一个简单的基于正则表达式的工具来尝试缩小更简单的情况,但似乎是半程序化,然后损坏了这个特定的代码. (我不知道它是否失败,因为这段代码也不时使用预处理条件,或者因为最长的匹配将会是10MB长,而Lua的正则表达式匹配器根本无法应对).我希望有广泛使用的工具或技术,可以扭转这个问题.我已经不得不使用astyle来清理代码中的其他一些风格的“问题”. astire的–remove-bracket选项几乎完成了我想要的,但是要求括号内的语句是单行上的单个语句,这在这里非常不一样(只是为了跨越“t”我检查过; astyle没有产生这个特殊的问题.)

编辑:对问题代码进行更深入的检查可以看出这样的事情:

  1. #if OneThing
  2. int num2296 = otherThing();
  3. #endif
  4. #if AnotherThing
  5. int num44 = otherThing()
  6. int num45 = 0;
  7. #endif
  8. int num72 = 0;
  9. #if OneThing
  10. int num45 = 0; // note: multiple equivalent declarations of num45
  11. #endif
  12. #if OneThing
  13. for(int num2297 = 0; num2297 < num2296; ++num2297) {
  14. num45 = doSomething(num2297);
  15. #endif
  16. #if AnotherThing
  17. for(int num43 = 0; num43 < num44; ++num43) {
  18. num45 = doSomething(num43);
  19. #endif
  20. if(somethingElse(num45)) {
  21. ++num72;
  22. }
  23. } // note: only one closing brace for the two protected by #ifs

代码的两个版本被编译为不同的目的,一个定义了OneThing,另一个定义了AnotherThing.然而,两者之间的大部分差异只是变量名,逻辑相同. (大多数,不是全部)

上面的代码段末尾的大括号就像为什么我的简单工具打破了.这也越来越像设计的工作安全,而不像无辜的无能. (如果代码曾经是由一个反编译器生成变量名称,如num2276的那一点,那么目前还不是这样).

不幸的是,这意味着一个自动化工具可能不会单独削减.我只需要通过,缓缓地解除最后程序员的伤害.我在这里离开这个问题,有一个奇迹工具,我不知道,可以将这两个版本转换为SSA,识别和折叠他们的逻辑等价,然后转换回来…

解决方法

您可以使用Roslyn重写代码.将源代码修改为文本不是一个好办法.使用Roslyn可以将其修改为语法树.

也许这有助于你平息一切?

  1. if (a)
  2. if (b) F2()
  3. else F3();
  4. else
  5. F4();

可能变成:

  1. if (a && b) F2();
  2. else if (a && !b) F3();
  3. else F4();

这样,源代码就变成一个平面的列表,在什么条件下输入一个分支是更明显的.

猜你在找的C#相关文章