Sol*_*zna 10 c# if-statement nested indentation
我目前不幸在为Somebody Else的C#代码工作,这真的让我大吃一惊.我不知道我之前的人是如何维护这段代码的,因为它的各种病态已经破坏了IDE,编译器,运行时环境......
我今天面临的问题涉及一个15兆字节的源文件,它具有真正令人难以置信的病态嵌套程度.代码如:
if(var == 0) {
// do stuff
}
else {
if(var == 1) {
// do stuff
}
else {
if(var == 2) {
// do stuff, identical word for word to the `var == 1` case
}
else {
// etc.
}
}
}
Run Code Online (Sandbox Code Playgroud)
在最好的时候,这是一个值得怀疑的风格选择.然而,这与代码的另一种病理结合:这些块中的一些深度接近千层.(我不屑于测量最深的是超过700),我真诚地希望这个人在我面前,作为其最终行为之一的,从这个代码被强行分开前,跑的造型工具,导致憎恶在我面前.我无法想象他们可能已经编写了这样的代码,特别是因为代码的每三或四次编辑都会崩溃IDE.(有时会删除我的源文件副本,作为奖励.)
我写了一个简单的基于正则表达式的工具来尝试压缩更简单的情况,但它似乎是半处理然后破坏了这个特定的代码.(我不确定它是否会失败,因为此代码也会不时使用预处理器条件,或者因为最长的匹配将近10MB长并且Lua的正则表达式匹配器无法应对.)我希望有一种广泛使用的工具或技术,可以扭转这个问题.我已经不得不使用astyle来清理代码所具有的其他风格"问题".--remove-bracketsastyle 的选项几乎可以达到我的要求,但要求括号中的语句在单行上是单个语句,这在这里并非如此......(而且只是为了跨越我的"t",我检查过; astyle并没有造成这个特殊的问题.)
编辑:对问题代码的深入检查揭示了这样的事情:
#if OneThing
int num2296 = otherThing();
#endif
#if AnotherThing
int num44 = otherThing()
int num45 = 0;
#endif
int num72 = 0;
#if OneThing
int num45 = 0; // note: multiple equivalent declarations of num45
#endif
#if OneThing
for(int num2297 = 0; num2297 < num2296; ++num2297) {
num45 = doSomething(num2297);
#endif
#if AnotherThing
for(int num43 = 0; num43 < num44; ++num43) {
num45 = doSomething(num43);
#endif
if(somethingElse(num45)) {
++num72;
}
} // note: only one closing brace for the two protected by #ifs
Run Code Online (Sandbox Code Playgroud)
此代码的两个版本是为不同目的编译的,一个定义了OneThing,另一个定义了AnotherThing.但是,两者之间的大多数差异只是变量名称,逻辑相同.(大多数,不是全部.)
像上面代码段末尾的大括号这样的案例解释了为什么我的简单工具破坏了.这也越来越像设计中的工作保障,而不像无辜的无能.(如果代码曾经在一个点,其中相同的变量名称num2276将由反编译来产生,它不是当前在该点).
不幸的是,这意味着自动化工具可能不会单独削减它.我只需要慢慢消除,慢慢消除最后一个程序员造成的伤害.我在这里留下这个问题,因为有一个神奇的工具,我不知道,可以将两个版本转换为SSA并识别和折叠它们的逻辑等价,然后将它们转换回来......
您可以使用Roslyn重写代码.将源代码修改为文本并不是一个好方法.使用Roslyn,您可以将其修改为语法树.
也许它可以帮助你压扁一切?
if (a)
if (b) F2()
else F3();
else
F4();
Run Code Online (Sandbox Code Playgroud)
可能成为:
if (a && b) F2();
else if (a && !b) F3();
else F4();
Run Code Online (Sandbox Code Playgroud)
这样,源代码就变成了一个平面列表,在输入分支的条件下更加明显.