2009-01-14 25 views
20

通常,当我使用lambda表达式时,我只是使用“a,b,c,d ...”作为变量名称,因为这些类型很容易推断出来,并且我发现短名称更易于阅读。这里有一个例子:Lambda变量名称 - 简称,还是不简称?

var someEnumerable = GetSomeEnumerable(); 
var somethingElseList = someEnumerable.Select(a => a.SomeProperty) 
             .OrderBy(a => a.SomePropertyField); 
var someDictionary = somethingElseList.ToDictionary(a => new SomeClass(a.Prop1), 
                a => a); 

有人质疑此命名,并希望看到长打出来的名字,如:

var someEnumerable = GetSomeEnumerable(); 
var somethingElseList = someEnumerable.Select(importantObj => importantObj.SomeProperty) 
             .OrderBy(objsInfo => objsInfo.SomePropertyField); 
var someDictionary = somethingElseList.ToDictionary(theInfoId => new SomeClass(theInfoId.Prop1), 
                theInfoId2 => theInfoId2); 

由于范围非常窄(在括号之间),除非你会变得愚蠢并且嵌套它们,我发现阅读短名称更容易。

没有深入了解我在以上使用的愚蠢命名示例,Lambda变量名称的一般共识是什么?要简称,还是不要简称?

回答

30

我平时的做法取决于你列举的集合。如果集合的名称意味着lambda参数将是什么类型,那么我只需要单个字母,但是如果集合不是描述性的,那么我会用一个词。

IE:

myCollection.Where(person =>....); //non descriptive collection name 

myPeopleCollection.Where(p=>...); // descriptive collection name 
9

我尝试使用单个字但有意义的名称。所以我会趋向使用“人”而不是“p”,但不会去“新加入的人”。

这同样适用于查询表达式以及 - 我可能快速一次性例子违反这一点,但我不一般喜欢:

from p in source 
where p.Age > 10 
select p.Name; 

我会很情愿看到

from person in source 
where person.Age > 10 
select person.Name; 
+0

是的,我倾向于在表达式语法中更好地命名,但那是因为范围更宽,并且可能变得混乱。 – TheSoftwareJedi 2009-01-14 16:04:30

+1

在表达式语法中,由于范围较宽,我通常会命名较长的名称。我没有看到写作.OrderBy(theInt => theInt)而不是.OrderBy(a => a)。 – TheSoftwareJedi 2009-01-14 16:15:08

+1

它使查询中该元素的更清晰。不幸的是,这并不总是显而易见的。 – 2009-01-14 16:24:32

5

我喜欢短名。我一直这么做。我主要在lambdas中使用i,y,x,但是我在sql中使用了a,b,c,d。

2

它可能会问了很多要求对“命名”共识'的问题。 :)

我同意“好名字的重要性”与名称的范围成正比。宁愿

from person in source ... 

的乔恩斯基特的回答是令人信服的,但如果名称中使用了很多,特别是如果输入的是更好的命名,我想我更喜欢

from p in persons ... 
+1

我看到质疑表达式语法中的命名与lambda语法中的命名不同。 – TheSoftwareJedi 2009-01-14 16:08:16

3

我说我同意贝丽。对我来说,这将取决于上下文,但我总是尽可能使其尽可能简洁。注意我说简洁,不简短。

这里是在LISP方言Clojure的两个例子:

user=> (def names ["ryan" "bob" "tom" "tim"]) 
#'user/names 

user=> (filter (fn [name] (.startsWith name "t")) names) 
("tom" "tim") 

对于那些不知道的Lisp/Clojure的,我的拉姆达是函数参数“过滤器”。那就是“(fn [name] ....)”。我选择在这里使用“名称”,因为它很简短,但描述了我正在使用的内容。但是,我认为'a','i','x'等就像可读性一样。

user=> (def odds (iterate (fn [n] (+ n 2)) 1)) 
#'user/odds 

user=> (take 5 odds) 
(1 3 5 7 9) 

在这里,我只是用'n'代表'数字'。我认为'数字'也可以,但对我的口味来说略显冗长。

我当然不会使用名字'nameOfPerson'或'previousOddNumber'。这只是太多的信息。我也尝试在大多数时间让我的名字保持不变,例如'nameString'。我发现大部分时间都是多余的信息。

就我个人而言,我认为这样的额外冗长的名字往往源自它帮助记录代码的想法。它似乎在像Java/C#这样的语言中尤其流行。我认为这可能是两种方式,这取决于程序员的风格。但是,名称越冗长,代码就越紧密(易读)。如果我的名字非常具体,而且它的功能经常发生变化,那么名称也可能会有很大的改变。最终,DEV可能会变得懒惰,并且最终会得到一个名称,该名称实际上并不描述变量的用途。这并不是问题,当且仅当程序员不认为名称是正确的。当然,这可能会在编译过程中很快得到解决(因为程序员会尝试划分两个字符串或某些类似的东西),但是它可能会导致大型项目中的时间浪费和混乱。

我也会为了简洁而争辩,因为屏幕的房地产。我仍然试着将我的行整理成80列,当'myVaraibleNameIsAsLongAsAParagraph'时这很难。

最终,我认为它总是会降低妥协。所以他们不喜欢'一个',但也许他们可以同意你应该争取'单词'或'数字'这样的单词,并避免那个可怕的骆驼案例。

对不起,这本书。

1

我带着一个,两个或三个字母,它们构成了所讨论对象的缩写表示。

Persons.Where(p => ...) 
AnalysisCode.Where(ac => ...) 
1

作为一般规则,我认为你对变量/对象/方法名称越明确越好。由于我们经常花费大部分时间阅读其他人的代码,因此我们越容易理解,越快您可以将注意力放在语法和逻辑上。如今,有了IntelliSense之类的功能,只要有可能,在清晰度方面犯错并不是一种真正的负担。

0

我同意@Johnny Wey;命名你的变量 - 出于同样的原因你用任何其他代码命名它们!仅仅因为代码的“内联”性质,不理解这种预测。可读性是关键 - 一目了然/无需将东西“悬停”;否则,你可能会说没有变量需要适当命名。如果使用“Enuerable”,可能会有一点余地,但仍然很高兴看到(再次一目了然)代码在做什么。如果变量类型推断依赖于传入类的某种泛型类型,请给它命名。使所有的代码像一个句子一样阅读;计算机应该适应我们(“人性化”),而不是我们开始像计算机那样行事的另一种方式,而只是因为我们可以/感觉更聪明/更像我们这样的科技怪才(我们有诱惑,我硝酸钾!)。键入明确的名称很容易,而且您仍然可以使用命名方法中的所有Intellisense /句子完成选项。另外,在lambda表达式的情况下悬停并不总是告诉你关于var的信息(在调试过程中令人沮丧),所以很高兴看到“清晰/足够有代表性”的命名,尤其是对于那些没有经过所有心理体操的新开发者来说能够通过遍历语句上下文来推断类型(这也可能是神秘的)。

0

如果变量的目的是明确的,缩短会更好。兰姆达斯呼​​吁写一种功能性的写作风格,因此你会看到很多单行的链接。它更清洁,看你什么时候把它们缩短。

另一种情况是,有时您需要声明一个在该范围内没有相关性/含义的虚拟变量。在这种情况下,我使用_,这对我来说很清楚。这都得心应手,尤其是在重载方法,用于例如,

public Foo Do() 
{ 
    return Do(_ => true); 
} 

public Foo Do(Func<T, bool> pattern) 
{ 
    return SomethingElse(pattern); 
} 
0

基于以上问题的答案,我认为这是普遍的共识是,如果你不能从你所处理的情况下讲,使用描述名字更好。例如:

entities.Where(person => person.Age >= 21); 

在上下文案件显而易见的,然而,单字母的名称实际上可能有助于可读性,因为它可以更容易把重点放在关键信息。例如:

people.Where(p => p.Age >= 21);people.Where(x => x.Age >= 21);

的问题是,这是更好的,px

  • 赞成p,它在SQL查询熟悉的模式,并提供了你所谈论的是Person一点点额外的提醒。
  • 赞成x,如果您将Person重命名为Customer,则不必担心修复所有的lambda参数。如果您使用过p,如果您的代码变为customers.Where(p => p.Age >= 21),实际上会有点令人困惑,而x基本上是不可知的。

我最近开始使用x,到目前为止,我没有注意到任何重大的缺点,但请评论,如果你不同意。

3

我们的团队不允许单字母变量,而不是拉姆达斯的事件。

我们发现,就像在TSQL中一样,代码越长越容易混淆。至于拉姆达的

我们会做这样的事情:

people.Where(personFound => personFound.FirstName.Contains("blah!")); 

这样,接下来的开发将不必看

people.Where(p => p.FirstName.Contains("blah")); 

看来可读的,但它总是在第一次做

什么联接

citizenShip.Join(people, c => c.personid, p => p.persoinid, (p, c) => new { p.FirstName, c.IsCitizen}) 
.Where(pc => pc.FirstName.Contains("blah"); 

相同变量名

citizenShip.Join(people, 
       citizenToJoin => citizenToJoin.personid, 
       personToJoin => personToJoin.persoinid, 
       (joinedPerson, joinedCitiznship) => 
        new { joinedPerson.FirstName, joinedCitiznship.IsCitizen}) 
.Where(personAndCitizenshipFound=> personAndCitizenshipFound.FirstName.Contains("blah"); 

哦,但是这是混乱和丑陋。只是使用不同的字母,所以它不那么容易混淆

citizenShip.Join(people, 
       c => c.personid, 
       p => p.persoinid, 
       (jp, pc) => 
        new { jp.FirstName, jc.IsCitizen}) 
.Where(pc => pc.FirstName.Contains("blah"); 

仍然令人困惑,但现在它更糟。因此,我们打破了拉姆达,以便我们为重构可读性

var peopleWithCitizenship = citizenShip.Join(people, 
              citizenToJoin => citizenToJoin.personid, 
              personToJoin => personToJoin.persoinid, 
              (joinedPerson, joinedCitiznship) => new { joinedPerson.FirstName, joinedCitiznship.IsCitizen}); 

var peopleWithCitizenshipFilteredByName = peopleWithCitizenship.Where(personAndCitizenshipFound=> personAndCitizenshipFound.FirstName.Contains("blah")); 

这不是一个很好的例子,但使代码可读性用很少的内幕知识。我们发现这暴露了复杂的代码(lambda),它需要分解成更小的块。