什么是惯用代码?


85

我会对一些c#前后示例,一些非惯用和惯用示例感兴趣。如果非c#示例理解了它们,也将很好。谢谢。


3
C#的隐藏功能充满了惯用的C#。并不是所有的人都介意您,但是很多带有高票数的简单的单线都可以被认为是惯用的。一些答案也描述了非惯用的替代方法。
Michiel van Oosterhout

Answers:


119

惯用语是指遵循语言惯例。您想找到完成任务的最简单,最常见的方法,而不是从其他语言移植知识。

非流行python使用带有附加的循环:

mylist = [1, 2, 3, 4]
newlist = []
for i in mylist:
    newlist.append(i * 2)

使用列表理解的惯用python:

mylist = [1, 2, 3, 4]
newlist = [(i * 2) for i in mylist] 

36

一些例子:

资源管理,非惯用语:

string content;
StreamReader sr = null;
try {
    File.OpenText(path);
    content = sr.ReadToEnd();
}
finally {
    if (sr != null) {
        sr.Close();
    }
}

惯用语:

string content;
using (StreamReader sr = File.OpenText(path)) {
    content = sr.ReadToEnd();
}

迭代,非惯用语:

for (int i=0;i<list.Count; i++) {
   DoSomething(list[i]);
}

也是非惯用语:

IEnumerator e = list.GetEnumerator();
do {
   DoSomenthing(e.Current);
} while (e.MoveNext());

惯用语:

foreach (Item item in list) {
   DoSomething(item);
}

过滤,非惯用语:

List<int> list2 = new List<int>();
for (int num in list1) {
  if (num>100) list2.Add(num);
}

惯用的:

var list2 = list1.Where(num=>num>100);

13
花括号是惯用的Java ;-)
Mathieu Guindon

15

惯用代码是用您的语言以通用方式执行通用任务的代码。它类似于设计模式,但是规模要小得多。习语因语言而异。C#中的一种习惯用法是使用迭代器遍历集合,而不是遍历整个集合。其他没有迭代器的语言可能依赖于循环习惯用法。


6

在PHP中,我有时会遇到如下代码:

foreach ($array as $value) {
    $trimmed[] = trim($value);
}
return $trimmed;

哪一个习惯上可以实现:

return array_map('trim', $array);

5

实际上,这意味着以一致的方式编写代码,即在您的代码库上工作的所有开发人员在编写类似的代码构造时都应遵循相同的约定。

因此,惯用方式是与其他代码的样式相匹配的方式,非惯用方式意味着您以不同的方式编写函数。

例如,如果要循环一定数量的项目,则可以通过几种方式编写循环:

for (int i = 0; i < itemCount; i++)

for (int i = 1; i <= itemCount; i++)

for (int i = 0; i < itemCount; ++i)

等等

最重要的是所选择的样式应始终使用。这样,人们对如何使用它就会变得非常熟悉并充满信心,并且当您监视外观不同的用法时,可能表示引入了错误,可能是一次失误,例如

for (int i = 1; i < itemCount; i++)

2
我想我认为惯用语是“最好的方法”,而不是武断的标准。但我认为最好的方法取决于具体情况。
MrBoJangles
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.