使用方法:var或对象名称类型?

bal*_*dre 53 c# anonymous-objects .net-3.5 c#-3.0

这是一个问题,在编程时我总是想知道:在编写代码时要使用什么:

var myFiles = Directory.GetFiles(fullPath);
Run Code Online (Sandbox Code Playgroud)

要么

string[] myFiles = Directory.GetFiles(fullPath);
Run Code Online (Sandbox Code Playgroud)

VAR是新的,是一个隐式类型的局部变量,所以我们只能在本地使用,它具有类似的规则不能为空,等等,但我不知道如果我们使用它"正常"的任何优势.

"常"的部分说,不是在匿名类型,对象和集合初始化查询表达式,其中这是使用var匿名对象的意图,所以我的意思是......就像上面的例子.

你的想法是什么?

Rob*_*ney 61

除了明显使用varLINQ之外,我还使用它来缩短毛状变量声明的可读性,例如:

var d = new Dictionary<string, Dictionary<string, Queue<SomeClass>>>();
Run Code Online (Sandbox Code Playgroud)

一般来说,我从静态类型中得到一种安慰(因为缺少一个更好的词),这让我不愿意放弃它.我喜欢当我宣布变量时我知道自己在做什么的感觉.声明变量不只是告诉编译器一些东西,它告诉读取代码的人.

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

List<string> list = MyMethod();
Run Code Online (Sandbox Code Playgroud)

显然,对吧?事实上,这是一个你可以轻松使用的地方var.

真的够了.但是这个版本的代码不只是声明一个变量,它告诉我编写它的人打算做什么:

IEnumerable<string> list = MyMethod();
Run Code Online (Sandbox Code Playgroud)

编写该代码的开发人员告诉我"我不打算更改此列表,也不会使用索引来访问其成员.我要做的就是遍历它." 这是在一行代码中获得的大量信息.这是你放弃使用的东西var.

当然,如果你没有首先使用它,你就不会放弃它.如果您是那种编写该行代码的开发人员,那么您已经知道不会var在那里使用.

编辑:

我只是重读了Jon Skeet的帖子,Eric Lippert的引用向我跳了出来:

隐式打印的本地人只是一种很小的方式,你可以在其中强调如何,从而强调什么.

我认为实际上在很多情况下使用隐式类型会留下隐含的内容.没关系到什么就可以了.例如,我会随便写一个LINQ查询,如:

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

当我阅读该代码时,我在阅读它时所想到的一件事就是" rows是一个" IEnumerable<DataRow>.因为我知道LINQ查询返回的是什么IEnumerable<T>,我可以在那里看到正在选择的对象的类型.

这是一个没有明确说明的情况.我可以推断它.

现在,在我使用LINQ的大约90%的情况下,这一点都无关紧要.因为90%的时间,下一行代码是:

foreach (DataRow r in rows)
Run Code Online (Sandbox Code Playgroud)

但是很难设想代码,其中声明rowsIEnumerable<DataRow>- 代码,其中查询许多不同类型的对象,将查询声明放在迭代旁边是不可行的,并且它将是有助于rows使用IntelliSense 进行检查.这是一件什么,而不是一件事.

  • 最后一点,我有点不同意."什么"并不意味着"它是什么类型",而是"它有什么好处".我知道"var rows"声明了一个包含我的行的变量.我还需要知道什么?据推测,它表现为行的集合,所以我并不关心精确类型. (3认同)

Jon*_*eet 42

你会对这个问题得到各种各样的意见 - 从"无处不在"到"只使用匿名类型的var,你基本上必须这样做".我喜欢Eric Lippert对它的看法:

所有代码都是抽象的.代码"真正"做的是操纵数据吗?号码?位?电压?电子?是的,但理解电子水平的代码是个坏主意!编码艺术正在弄清楚正确的抽象层次对于受众来说是什么.

在高级语言中,代码所做的(语义上)和代码如何实现它之间始终存在这种紧张关系.维护程序员需要了解他们如何成功进行更改的内容和方式.

LINQ的重点在于它大量不再强调"如何",并大量强调"什么".通过使用查询理解,程序员对未来的观众说:"我相信你既不知道也不关心如何计算这个结果集,但你应该非常关心结果集的语义是什么." 它们使代码更接近正在实施的业务流程,并且远离使其成为可能的位和电子.

隐式打印的本地人只是一种很小的方式,你可以在其中强调如何,从而强调什么.在特定情况下,这是否是正确的做法是判断.所以我告诉人们,如果类型的知识是相关的,并且它的选择对于方法的持续操作是至关重要的,那么不要使用隐式类型.明确的打字说"我告诉你这是怎么起作用的原因,要注意".隐式打字说"这个东西是List还是Customer [无关紧要",重要的是它是一个客户集合."

我个人不倾向于使用它,如果类型不明显 - 我把LINQ查询包含为"相当明显".Directory.GetFiles例如,我不会这样做,因为它不是很明显,string[]而是返回a 而不是(比如说)a FileInfo[](或者完全不同的东西) - 这对你以后做的事情有很大影响.

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

  • 我做的非常相似.但是,除了右侧的构造函数调用之外,如果右侧是铸造的,我也总是使用它,即最后有一个"as MyType". (3认同)
  • 从现在开始,"电子操纵器"将成为我的官方功能:p (3认同)

ang*_*son 11

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

  1. 使用匿名类型,即.与LINQ相关(在某些情况下需要var)
  2. 当语句声明并构造相同类型的特定类型时

即.这是第2点的一个例子:

var names = new List<String>();
Run Code Online (Sandbox Code Playgroud)

编辑:这是对Jon Skeet的回答.

事实上,上述答案已经简化.基本上,我使用var,其类型是:

  1. 不必知道(虽然不是很多地方)
  2. 不可能知道(LINQ,匿名类型)
  3. 否则已知,或从代码中清除

在工厂方法的情况下,您在编写代码的地方需要知道的是,您获取的对象是某种类型的后代,并且某些类型具有静态工厂方法,那么我会使用变种.像这样:

var connection = DatabaseConnection.CreateFromConnectionString("...");
Run Code Online (Sandbox Code Playgroud)

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


Ini*_*eer 9

我尝试了"使用无处不在"的风格......这就是为什么我没有继续使用它.

  1. 有时可读性下降
  2. 在=之后限制智能感知
  3. 输入"var"确实并不比输入"int","string"等短得多,特别是对于intellisense.

话虽如此,我仍然使用它与LINQ.