多年前,他们曾经是一场比赛,看谁能制作出最混淆的C代码,而且有些结果显然难以理解。 C就是这样。你可以特别用预处理器搞砸了。
但是,C#的许多新功能提供了一个混淆代码的绝佳机会。我想知道是否有人对在代码中的简洁和清晰度之间找到正确的平衡有意见。让我举一个讨论的例子,即将项目填充到ListView中的任务。 (是的,我知道你可以用数据绑定来做,但请跟我一起去。)
控件是两列,用数组填充 结构人 { 公共字符串名称; 公共字符串地址; };
一个简单明了的方法是:
private void Fill(Person[] people)
{
foreach(Person person in people)
{
string[] columns = new string[2];
columns[0] = person.name;
columns[1] = person.address;
ListViewItem item = new ListViewItem(columns);
listView1.items.Add(item);
}
}
清晰易懂。
我也可以这样写:
private void Fill(Person[] people)
{
foreach(Person person in people)
{
string[] columns = new string[] { person.name, person.address };
ListViewItem item = new ListViewItem(columns);
listView1.items.Add(item);
}
}
甚至:
private void Fill(Person[] people)
{
foreach(var person in people) // Note use implicit typing here
{
listView1.items.Add(new ListViewItem(
new string[] { person.name, person.address }));
}
}
最后,我也可以这样写:
private void Fill(Person[] people)
{
Array.ForEach(people, item =>
listView1.items.Add(new ListViewItem(
new string[] { person.name, person.address}));
}
每个人都或多或少地使用该语言的各种新功能。你如何找到简洁和清晰之间的平衡?我们是否应该举行年度混淆C#比赛?
答案 0 :(得分:24)
你知道什么难吗?编写其他人可以阅读和维护的代码。任何白痴都可以编写编译并且无法维护的代码。
始终支持可维护性:这就是您找到余额的方式。
修改强>
“任何傻瓜都可以编写计算机可以理解的代码。优秀的程序员编写人类可以理解的代码。”
- Martin Fowler,Refactoring:改进现有代码的设计
感谢roygbiv找到上述报价。向福勒道歉,谋杀他的言论;我知道我以前读过它,我只是不记得在哪里。
答案 1 :(得分:6)
将所有内容填充到一行并不会使其“混淆” - 它只会使您不必要地滚动。对于那些了解C#的人来说理解你提出的任何一个例子仍然是微不足道的,如果你使用了换行符,那么没有一个会比其他人更好或更差。
答案 2 :(得分:2)
最高可读性代码,但:
请记住,多余的冗长和句法噪音会影响可读性。如果更简洁的符号允许您更直接地表达您的意图,则更简洁可以与提高的可读性相吻合。例如,比较真正的lambda函数,用单方法接口模拟它们。
假设其他读过您代码的人都是体面的程序员,并且知道您正在使用的语言。不要假设语言律师知识水平,但要具备良好的工作知识。不要编码到最低的公分母,因为虽然代码猴子可以使代码更易于维护,但它会让你和实际知道他们正在做什么的维护程序员感到烦恼。
更具体地说,示例1对于如此简单的事情具有太多的语法噪声。实例4对于人来说非常难以解析。我会说2和3都很不错,但是在例3的情况下我会重新格式化它,只是为了让人们更容易解析所有函数调用嵌套:
private void Fill(Person[] people)
{
foreach(var person in people)
{
listView1.items.Add(
new ListViewItem(
new string[] { person.name, person.address }
)
);
}
}
现在你拥有两全其美:它可以很容易地被人类解析,并且没有任何多余的,不必要的冗长的临时变量。
编辑:我也认为使用隐式变量输入,即var
在大多数时候都很好。人们在动态语言中编写完全可读的代码,其中隐式类型是唯一的类型,并且大多数情况下,变量的形式类型是低级细节,与代码的高级意图几乎没有关系。
答案 3 :(得分:1)
至少就你在这里提供的例子而言,我并不认为混淆会随着你的进展而上升,直到你到达最后一个。即使在那里,任何歧义的唯一原因是Lambda的存在,这只需要一些人习惯。所以,一个新手可能会遇到最后一个问题,但不应该发现其他人在旧的狂野C竞赛条目不可读的情况下是不可读的。
不同之处在于这些C#示例都处于相同的抽象级别 - 更简洁的示例只是删除了“fluff”。在C中,由于A)任意重命名/别名结构和B)捆绑在一个语句中的几个级别的内存访问,你有机会产生歧义。
总而言之,你可以用任何语言来模糊代码,但我不认为C#很容易像C一样,事实上,我认为它比许多语言更清晰 - 即使使用了一些语言更先进的结构。
答案 4 :(得分:1)
C#和VB.NET语言的设计目的是为了更加清晰,因为它们的运行级别高于C. C编程接近金属可以说。通过设计编写模糊的C#是不可能的,就像C语言一样。
“任何傻瓜都可以编写计算机可以理解的代码。优秀的程序员编写人类可以理解的代码。”
- Martin Fowler,Refactoring:改进现有代码的设计
答案 5 :(得分:0)
我发现这个例子没有被混淆。
首先,意图是如此痛苦地清楚,新手更有可能学习lambda的作用而不是理解代码。哪个是使用更“先进”技术的理想场所 - 即使是那些不了解他们所做的事情的人也能理解他们“应该”做什么。
其次,以上所有内容不仅没有被混淆,而且完全是惯用的C#。最后一个可能不是因为没有那么广泛使用Array.ForEach,大多数人(我曾与之合作过)会使用LINQ。