这是一个在编程时我总是想知道的问题:当我们编写代码时使用什么:
var myFiles = Directory.GetFiles(fullPath);
或者
string[] myFiles = Directory.GetFiles(fullPath);
var是新的并且是隐式类型局部变量 em>,所以我们只能在本地使用,并且它有诸如不能为空等规则,但我想知道我们“正常”使用它是否有任何优势。
“通常”部分表示,不在匿名类型、对象和集合初始化器和查询表达式中使用 var 匿名对象,所以我的意思是......就像上面的例子一样。
你怎么看?
this is a question that when programming I always wonder: What to use when we are writing code:
var myFiles = Directory.GetFiles(fullPath);
or
string[] myFiles = Directory.GetFiles(fullPath);
var is new and is a Implicitly Typed Local Variables, so we can only use locally and it has rules like can't be null, etc., but I wonder if we get any advantage of using it "normally".
The "normally" part says, not in Anonymous Types, Object and Collection Initializers and Query Expressions where that was the intent to use the var anonymous object, so what I mean is... just like the example above.
what are your thoughts?
发布评论
评论(8)
除了在 LINQ 中明显使用
var
之外,我还使用它来缩写毛茸茸的变量声明以提高可读性,例如:一般来说,我从静态类型中获得了一种安慰(因为需要一个更好的词)这让我不愿意放弃。 我喜欢在声明变量时知道自己在做什么的感觉。 声明变量不仅仅是告诉编译器一些事情,它还告诉阅读代码的人一些事情。
让我举一个例子。 假设我有一个返回
List
的方法。 这段代码当然是正确的,我认为 90% 的 C# 开发人员可能会这样编写它:显然,对吧? 事实上,您可以在此处轻松使用
var
。确实如此。 但是这个版本的代码不仅仅是声明一个变量,它还告诉我编写该代码的人打算做什么:
编写该代码的开发人员告诉我“我不会要更改此列表,我也不会使用索引来访问其成员,我要做的就是迭代它。” 在一行代码中可以传达大量信息。 如果您使用
var
,那么您就放弃了这一点。当然,如果您一开始就没有使用它,您就不会放弃它。 如果您是那种会编写该行代码的开发人员,那么您已经知道您不会在那里使用
var
。编辑:
我刚刚重读了乔恩·斯基特 (Jon Skeet) 的帖子,埃里克·利珀特 (Eric Lippert) 的这句话突然引起了我的注意:
我认为实际上在很多情况下使用隐式类型会留下隐式内容。 不要纠结于“什么”就可以了。 例如,我会随意编写一个 LINQ 查询,如下所示:
当我阅读该代码时,我想到的一件事是“
rows
是一个IEnumerable”。 。” 因为我知道 LINQ 查询返回的是
IEnumerable
,并且我可以在那里看到正在选择的对象的类型。在这种情况下,“什么”尚未明确。 这就留给我去推断了。
现在,在我使用 LINQ 的大约 90% 的情况下,这一点并不重要。 因为 90% 的情况下,下一行代码是:
但是不难想象,将
rows
声明为IEnumerable
会非常有用。 - 正在查询许多不同类型的对象的代码,将查询声明放在迭代旁边是不可行的,并且能够使用 IntelliSense 检查行
会很有用。 这是一个“是什么”的问题,而不是一个“如何”的问题。Beyond the obvious use of
var
with LINQ, I also use it to abbreviate hairy variable declarations for readability, e.g.:In general, I get a kind of comfort (for want of a better word) from static typing that makes me reluctant to give it up. I like the feeling that I know what I'm doing when I'm declaring a variable. Declaring a variable isn't just telling the compiler something, it's telling the person reading your code something.
Let me give you an example. Suppose I have a method that returns a
List<string>
. This code is certainly correct, and I think it's how 90% of C# developers would probably write it:Obviously, right? In fact, here's a place you could just as easily use
var
.True enough. But this version of the code isn't just declaring a variable, it's telling me what the person who wrote it is intending to do:
The developer who wrote that code is telling me "I'm not going to be changing this list, nor am I going to use an index to access its members. All I'm going to do is iterate across it." That's a lot of information to get across in a single line of code. It's something you give up if you use
var
.Of course, you're not giving it up if you weren't using it in the first place. If you're the kind of developer who would write that line of code, you already know that you wouldn't use
var
there.Edit:
I just reread Jon Skeet's post, and this quote from Eric Lippert jumped out at me:
I think that actually in a lot of cases using implicit typing is leaving the what implicit. It's just OK to not dwell on the what. For instance, I'll casually write a LINQ query like:
When I read that code, one of the things I think when I'm reading it is "
rows
is anIEnumerable<DataRow>
." Because I know that what LINQ queries return isIEnumerable<T>
, and I can see the type of the object being selected right there.That's a case where the what hasn't been made explicit. It's been left for me to infer.
Now, in about 90% of the cases where I use LINQ, this doesn't matter one tiny little bit. Because 90% of the time, the next line of code is:
But it's not hard to envision code in which it would be very useful to declare
rows
asIEnumerable<DataRow>
- code where a lot of different kinds of objects were being queried, it wasn't feasible to put the query declaration next to the iteration, and it would be useful to be able inspectrows
with IntelliSense. And that's a what thing, not a how thing.关于这个问题,您会得到各种各样的意见 - 从“到处使用 var”到“只在必须使用匿名类型的情况下才使用 var”。 我喜欢Eric Lippert 的看法:
如果类型不是相当明显的话,我倾向于使用它 - 我将 LINQ 查询包含为“相当明显”。我不会这样做例如,
Directory.GetFiles
,因为返回一个string[]
而不是(比如说)一个FileInfo[]
(或者完全是别的东西) - 这对你以后所做的事情有很大的不同,如果赋值运算符的右侧有一个构造函数调用,我更有可能使用
var
:类型非常明显,这对于复杂的泛型类型尤其方便,例如Dictionary>
。You'll get a huge variety of opinions on this one - from "use var everywhere" to "only use var with anonymous types, where you basically have to." I like Eric Lippert's take on it:
Personally I don't tend to use it if the type isn't reasonably obvious - where I include LINQ queries as being "reasonably obvious". I wouldn't do it for
Directory.GetFiles
for instance, as it's not really obvious that that returns astring[]
instead of (say) aFileInfo[]
(or something else entirely) - and that makes a big difference to what you do later.If there's a constructor call on the right hand side of the assignment operator, I'm much more likely to go with
var
: it's blatantly obvious what the type will be. This is particularly handy with complex generic types, e.g.Dictionary<string,List<int>>
.就我个人而言,我只在两个地方使用 var:
即。 这是第 2 点的示例:
已编辑:这是对 Jon Skeet 问题的回应。
上面的答案其实已经被简化了。 基本上,我使用 var,其中类型是:
否则已知,或从 工厂方法,您在编写代码的地方需要知道的是您返回的对象是某种类型的后代,并且某种类型有一个静态工厂方法,然后我将使用var。 像这样:
上面的例子是我的代码中的一个真实例子。 很明显,至少对于我和使用此代码的人来说,connection 是 DatabaseConnection 的后代,但理解代码和使用代码都不需要确切的类型。
Personally I only use var in two places:
ie. this is an example of point 2:
Edited: This in response to Jon Skeet's question.
The above answer was in fact simplified. Basically, I use var where the type is either:
In the case of a factory method, where all you need to know at the place where you write the code is that the object you get back is a descendant of some type, and that some type has a static factory method, then I would use var. Like this:
The above example is a real example from my code. It is clear, at least to me and the people that use this code, that connection is a DatabaseConnection descendant, but the exact type is not needed for neither understanding the code, nor using it.
我尝试了“到处使用 var”风格...这就是我没有继续使用它的原因。
尽管如此,我仍然将它与 LINQ 一起使用。
I tried the "use var everywhere" style... and here is why I didn't continue to use it.
With that said, I DO still use it with LINQ.
来自函数式编程领域,这里类型推断占主导地位,我尽可能对所有本地变量使用
var
。在 Visual Studio 中,如果您想知道任何本地变量的类型是什么,您只需将鼠标悬停在它上面即可。
Coming from the land of functional programming, where type-inference rules the day, I use
var
for all locals wherever possible.In Visual Studio, if you are ever wondering what the type of any local is, all you have to do is hover over it with your mouse.
我倾向于在任何地方使用
var
,但我的同事说停止,它对我们来说可读性较差。 所以我现在只在匿名类型、LINQ 查询以及右侧的构造函数中使用var
。I tend to use
var
everywhere, but my co-workers said stop, it is less readable to us. So I now I usevar
only on anonymous types, LINQ queries and where is constructor on right side.这个 post 对于何时使用 var 类型接口或对象类型有一些很好的指导。
This post have some good guidlines on when to use var type interface or object types.
我认为注意到 Haskell 中通常如何处理这个问题很有趣。 感谢 Curry-Howard 同构,任何表达式的(最通用的)类型Haskell 是可以推断的,因此基本上任何地方都不需要类型声明,除了少数例外; 例如,有时您故意希望将类型限制为比推断更具体的类型。
当然,要求的和推荐的不是一回事; 实际上,惯例似乎是顶级定义总是具有类型声明,而本地化定义则省略类型声明。 这似乎在整个定义的明确性可读性与局部“帮助器”或“临时”定义的简洁性可读性之间取得了良好的平衡。 如果我理解正确的话,你首先不能将 var 用于“顶级”定义(如方法或全局函数),所以我想这会翻译为“使用 var 在 C# 世界中随处可见”。 当然,键入“
int
”与“var
”的击键次数相同,但大多数示例都会比这个更长。I think it's interesting to note how this is usually handled in Haskell. Thanks to the Curry-Howard isomorphism, the (most general) type of any expression in Haskell can be inferred, and thus type declarations are essentially not required anywhere, with a few exceptions; for example, sometimes you deliberately want to limit the type to something more specific than would be inferred.
Of course, what is required and what is recommended are not the same thing; in practice, the convention seems to be that top-level definitions always have type declarations, while localised definitions have the type declarations left out. This seems to strike a good balance between explicitness-for-readability of the definition as a whole, contrasted with brevity-for-readability of the local "helper" or "temporary" definitions. If I understand correctly, you can't use
var
for "top-level" definitions (like a method or global function) in the first place, so I guess this translates to "usevar
everywhere you can" in C# world. Of course, typing "int
" is the same number of keystrokes as "var
", but most examples will be longer than that.