2008-10-25 57 views
50

这是一个问题,在编程时,我总是在想:当我们在写代码怎么用:使用什么:var或对象名称类型?

var myFiles = Directory.GetFiles(fullPath); 

string[] myFiles = Directory.GetFiles(fullPath); 

VAR是新的,是一个隐式类型局部变量,所以我们只能在本地使用,它的规则不能为空等,但我不知道我们是否有“正常”使用它的优势。

“常”的部分说,不匿名类型对象和集合初始化查询表达式哪里,这是使用VAR匿名对象的意图,所以我的意思是...只是像上面的例子。

你有什么想法?

+2

伟大的问题。 – Contango 2010-10-18 17:44:02

回答

59

除了明显的使用var与LINQ,我还用它来简化毛茸茸的变量声明为便于阅读,如:

var d = new Dictionary<string, Dictionary<string, Queue<SomeClass>>>(); 

在一般情况下,我得到一种安慰(对于一个更好的词想)从静态打字,这让我不愿意放弃它。我喜欢这种感觉,即当我声明一个变量时,我知道自己在做什么。声明一个变量不仅仅是告诉编译器一些东西,而是告诉读取代码的人。

让我给你举个例子。假设我有一个返回List<string>的方法。这段代码当然是正确的,我认为90%的C#开发人员可能会这么写:

List<string> list = MyMethod(); 

显然,对吗?事实上,这里可以轻松使用var

够正确。但是版本的代码不只是声明一个变量,它告诉我什么是谁写的,它正试图做的人:

IEnumerable<string> list = MyMethod(); 

谁写的开发代码是告诉我:“我不会改变这个列表,我也不会使用索引来访问它的成员,我要做的就是遍历它。“这是在单行代码中获得的大量信息。如果你使用var,这是你放弃的东西。

当然,如果你不是首先使用它,你并没有放弃它。如果你是那种会写这行代码的开发者,那么你已经知道你不会在那里使用var

编辑:

我只是重读乔恩斯基特的帖子,并从埃里克利珀这句话在我跳了出来:

隐式类型当地人都在其中您可以淡化的只是一个小方法如何从而强调什么。

我觉得实际上在很多情况下使用隐式打字就是留下什么隐含的。只是没有详细说明。当我读到这些代码,当我读它是“rowsIEnumerable<DataRow>我想的事情之一

var rows = from DataRow r in parentRow.GetChildRows(myRelation) 
      where r.Field<bool>("Flag") 
      orderby r.Field<int>("SortKey") 
      select r; 

:比如,我随便写LINQ查询等。“因为我知道什么LINQ查询返回的IEnumerable<T>,我可以看到被选择在那里的对象的类型。

这其中有什么没有已经作出了明确的情况下,它已经离我而去。推断

现在,在这里我使用LINQ的案件约90%,这不要紧,一个小小的点点,因为时间的90%,代码的下一行是:

foreach (DataRow r in rows) 

但是,设想将rows声明为非常有用的代码并不难IEnumerable<DataRow> - 代码中查询了很多不同种类的对象,将查询声明放在迭代旁边是不可行的,并且能够使用IntelliSense检查rows会很有用。这是一件什么事,而不是一件事。

41

对这个问题你会得到各种各样的意见 - 从“use var everywhere”到“只使用var,匿名类型,你基本必须这样做”。我喜欢Eric Lippert's take on it

所有的代码都是抽象的。代码是“真的”在做什么 是 操纵数据?号码?位? 编号电压?电子号?是的,但 了解代码在 的水平是一个坏主意! 编码的艺术就是搞清 受众的抽象层次是什么。

在高级语言有 总是什么 代码做(在语义上)之间的这种张力和HOW的 代码完成它。维护 程序员需要了解 什么以及他们如何去做 才能成功进行更改。

LINQ的重点在于它大量地强调了“怎么样”和“大力”强调“什么”。通过使用查询综合 ,该 程序员说未来 观众:“我认为,你应该 既不知道也不关心这个 结果集究竟是如何被计算的,但你 应该非常关心的 语义什么的结果集是“。 他们使代码更接近 正在实施的业务流程和 远离位和电子 使它走。

隐式键入的当地人只是一个小的方式,在这种方式中,您可以不强调 的方式,从而强调 什么。在特定情况下, 是否是 判断呼叫。所以我告诉人们, 如果知识类型是相关的 和它的选择是至关重要的 继续操作的方法, 然后不使用隐式键入。 明确的打字说:“我告诉你 这是如何工作的原因,支付 注意力”。隐式类型说“它 无关紧要这个 事情是一个List还是一个 Customer [],重要的是它是一个客户集合的 。”

我个人不倾向于使用它,如果类型是不是相当明显 - 其中包括我的LINQ查询为“相当明显”。举例来说,我不会这样做,因为它不是很明显,那会返回一个string[]而不是(比如说)FileInfo[](或者其他的东西) - 这对你以后的工作会产生很大的影响。

如果在赋值运算符的右边有一个构造函数调用,我更有可能使用var:它显然是明显的类型。这对于复杂的泛型类型尤其方便。 Dictionary<string,List<int>>

+3

我做得非常相似。但是,除了右侧的构造函数调用外,如果右侧已经被转换,我也总是使用它,即最后有一个“as MyType”。 – OregonGhost 2008-10-25 20:03:37

+3

从现在开始,“电子机械手”将成为我的官方职能:p – dvdvorle 2013-05-15 07:41:52

11

我个人只在两个地方使用VAR:

  1. 使用匿名类型,即。 LINQ有关(其中在某些情况下,需要VAR)
  2. 当语句声明,并在同一类型

即构建一个特定的类型。这是点2的一个例子:响应于乔恩斯基特的质询这:

var names = new List<String>(); 

编辑

上面的答案其实已经简化了。基本上,我用VAR其中类型可以是:

  1. 不必要知道(不,很多地方虽然)
  2. 不可能知道(LINQ,匿名类型)
  3. 否则已知的,或者清楚代码

在一个工厂方法,所有你需要知道你写的代码的地方的情况是,你回来的对象是某种类型的后裔,而某种类型有一个静态的工厂方法,那么我会用var。像这样:

var connection = DatabaseConnection.CreateFromConnectionString("..."); 

上面的例子是我的代码中的一个真实例子。很明显,至少对我和使用此代码的人来说,连接是一个DatabaseConnection后代,但确切类型并不需要理解代码,也不需要使用它。

+0

静态工厂方法如何? Foo.CreateInstance(...)? – 2008-10-25 19:36:36

9

我试过“使用无处不在”风格......这就是为什么我没有继续使用它。

  1. 有时降级可读性
  2. 限制智能感知后=
  3. 键入“无功”真的不是不是键入“诠释”,“串”等,尤其是智能感知短得多。

就这样说,我仍然在LINQ中使用它。

3

这个post关于何时使用var类型的接口或对象类型有一些很好的指导。

1

我觉得有趣的是,这些通常是在Haskell中处理的。由于Curry-Howard isomorphism,可以推断出Haskell中任何表达式的(最一般的)类型,因此类型声明本质上不是必需的,除少数例外;例如,有时你会故意将类型限制为比推断的更具体的类型。

当然,要求什么和推荐什么是不一样的;在实践中,该惯例似乎是顶级定义总是有类型声明,而本地化定义则省略了类型声明。这似乎在整个定义的明确性与可读性之间取得了很好的平衡,与本地“助手”或“临时”定义的简洁性 - 可读性形成对比。如果我理解正确,首先你不能使用var作为“顶级”定义(如方法或全局函数),所以我想这意味着在C#世界中“在任何地方都可以使用var”。当然,输入“int”的键击次数与“var”的键击次数相同,但大多数例子都会比这个长。

3

来自函数式编程的领域,类型推理规则当天,我尽可能为所有当地人使用var

在Visual Studio中,如果您想知道任何本地类型是什么,您只需用鼠标将其悬停在其上即可。

3

我倾向于在任何地方都使用var,但我的同事说停下来,它对我们的可读性不好。所以我现在只对匿名类型,LINQ查询使用var,右侧的构造函数在哪里。

相关问题