C# 使用什么:var 或对象名称类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/236878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:18:38  来源:igfitidea点击:

What to use: var or object name type?

c#.net-3.5c#-3.0anonymous-objects

提问by balexandre

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);

varis 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".

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

The "normally" part says, not in Anonymous Types, Object and Collection Initializersand Query Expressionswhere that was the intent to use the var anonymous object, so what I mean is... just like the example above.

“通常”部分说,不是在Anonymous TypesObject 和 Collection Initializers以及Query Expressions中,其中意图使用 var 匿名对象,所以我的意思是......就像上面的例子一样。

what are your thoughts?

你怎么看?

采纳答案by Robert Rossney

Beyond the obvious use of varwith LINQ, I also use it to abbreviate hairy variable declarations for readability, e.g.:

除了var与 LINQ的明显使用之外,我还使用它来缩写多毛变量声明以提高可读性,例如:

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

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:

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

List<string> list = MyMethod();

Obviously, right? In fact, here's a place you could just as easily use var.

很明显,对吧?事实上,这里有一个您可以轻松使用的地方var

True enough. But thisversion of the code isn't just declaring a variable, it's telling me what the person who wrote it is intending to do:

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

IEnumerable<string> list = MyMethod();

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.

编写该代码的开发人员告诉我“我不会更改此列表,也不会使用索引来访问其成员。我要做的就是遍历它。” 一行代码就包含了大量信息。如果您使用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 varthere.

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

Edit:

编辑:

I just reread Jon Skeet's post, and this quote from Eric Lippert jumped out at me:

我刚刚重读了 Jon Skeet 的帖子,Eric Lippert 的这句话让我印象深刻:

Implicitly typed locals are just one small way in which you can deemphasize the how and thereby emphasize the what.

隐式键入的局部变量只是一种小方法,您可以在其中淡化如何强调内容,从而强调内容。

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:

我认为实际上在很多情况下使用隐式类型是隐式的。不纠结于什么是可以的。例如,我会随便写一个 LINQ 查询,如:

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

When I read that code, one of the things I think when I'm reading it is "rowsis an IEnumerable<DataRow>." Because I know that what LINQ queries return is IEnumerable<T>, and I can see the type of the object being selected right there.

当我阅读该代码时,我在阅读它时想到的一件事是“rows是一个IEnumerable<DataRow>.”。因为我知道 LINQ 查询返回的是IEnumerable<T>,并且我可以在那里看到被选择的对象的类型。

That's a case where the what hasn'tbeen 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:

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

foreach (DataRow r in rows)

But it's not hard to envision code in which it would be very useful to declare rowsas IEnumerable<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 inspect rowswith IntelliSense. And that's a what thing, not a how thing.

但是不难想象在代码中声明rows为非常有用的IEnumerable<DataRow>代码,其中查询了许多不同类型的对象,将查询声明放在迭代旁边是不可行的,这将是能够rows使用 IntelliSense进行检查很有用。这是一个什么事情,而不是一个怎么样的事情。

回答by Jon Skeet

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:

关于这个,你会得到各种各样的意见——从“到处使用 var”到“只对匿名类型使用 var,你基本上必须这样做”。我喜欢Eric Lippert 的看法

All code is an abstraction. Is what the code is “really” doing is manipulating data? No. Numbers? Bits? No. Voltages? No. Electrons? Yes, but understanding the code at the level of electrons is a bad idea! The art of coding is figuring out what the right level of abstraction is for the audience.

In a high level language there is always this tension between WHAT the code does (semantically) and HOW the code accomplishes it. Maintenance programmers need to understand both the what and the how if they're going to be successful in making changes.

The whole point of LINQ is that it massively de-emphasizes the "how" and massively emphasizes the "what". By using a query comprehension, the programmer is saying to the future audience "I believe that you should neither know nor care exactly how this result set is being computed, but you should care very much about what the semantics of the resulting set are." They make the code closer to the business process being implemented and farther from the bits and electrons that make it go.

Implicitly typed locals are just one small way in which you can deemphasize the how and thereby emphasize the what. Whether that is the right thing to do in a particular case is a judgment call. So I tell people that if knowledge of the type is relevant and its choice is crucial to the continued operation of the method, then do not use implicit typing. Explicit typing says "I am telling you how this works for a reason, pay attention". Implicit typing says "it doesn't matter a bit whether this thing is a List or a Customer[], what matters is that it is a collection of customers."

所有的代码都是抽象的。代码“真正”做的是操作数据吗?号码?位?没有。电压?不。电子?是的,但是在电子级别理解代码是个坏主意!编码的艺术就是弄清楚对观众来说什么是正确的抽象级别。

在高级语言中,代码做什么(语义上)和代码如何完成它之间总是存在这种紧张关系。维护程序员需要了解什么以及如何才能成功进行更改。

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

隐式键入的局部变量只是一种小方法,您可以在其中淡化如何强调内容,从而强调内容。在特定情况下这样做是否正确是一种判断。所以我告诉人们,如果类型的知识是相关的,并且它的选择对方法的继续运行至关重要,那么不要使用隐式类型。显式输入表示“我告诉您这是有原因的,请注意”。隐式输入表示“这个东西是 List 还是 Customer[] 并不重要,重要的是它是一个客户的集合。”

Personally I don't tendto 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.GetFilesfor instance, as it's not really obvious that that returns a string[]instead of (say) a FileInfo[](or something else entirely) - and that makes a big difference to what you do later.

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

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:类型是什么是显而易见的。这对于复杂的泛型类型特别方便,例如Dictionary<string,List<int>>.

回答by Lasse V. Karlsen

Personally I only use var in two places:

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

  1. With anonymous types, ie. LINQ-related (where var is required in some cases)
  2. When the statement declares and constructs a specific type at the same type
  1. 使用匿名类型,即。LINQ 相关(在某些情况下需要 var)
  2. 当语句声明并构造相同类型的特定类型时

ie. this is an example of point 2:

IE。这是第 2 点的示例:

var names = new List<String>();

Edited: This in response to Jon Skeet's question.

编辑:这是对 Jon Skeet 问题的回应。

The above answer was in fact simplified. Basically, I use varwhere the type is either:

上面的答案实际上被简化了。基本上,我使用var,其中类型是:

  1. Unnecessary to know (not that many places though)
  2. Impossible to know (LINQ, anonymous types)
  3. Otherwise known, or clear from the code
  1. 不必要知道(虽然没有那么多地方)
  2. 不可能知道(LINQ,匿名类型)
  3. 否则已知,或从代码中清除

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 typehas a static factory method, then I would use var. Like this:

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

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

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 connectionis a DatabaseConnection descendant, but the exact type is not needed for neither understanding the code, nor using it.

上面的例子是我的代码中的一个真实例子。很明显,至少对我和使用此代码的人而言,该连接是 DatabaseConnection 的后代,但无论是理解代码还是使用它,都不需要确切的类型。

回答by Inisheer

I tried the "use var everywhere" style... and here is why I didn't continue to use it.

我尝试了“随处使用 var”的风格……这就是我没有继续使用它的原因。

  1. Degraded readability at times
  2. Limits Intellisense after =
  3. Typing "var" really wasn't much shorter than typing "int", "string", etc., especially with intellisense.
  1. 有时会降低可读性
  2. 在 = 之后限制智能感知
  3. 键入“var”确实并不比键入“int”、“string”等短多少,尤其是使用智能感知。

With that said, I DO still use it with LINQ.

话虽如此,我仍然将它与 LINQ 一起使用。

回答by Andres Denkberg

This posthave some good guidlines on when to use var type interface or object types.

这篇文章有一些关于何时使用 var 类型接口或对象类型的很好的指导方针。

回答by mithrandi

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.

我认为在 Haskell 中通常如何处理这点很有趣。感谢Curry-Howard 同构,可以推断出 Haskell 中任何表达式的(最通用的)类型,因此基本上不需要在任何地方进行类型声明,只有少数例外;例如,有时您有意将类型限制为比推断的更具体的内容。

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 varfor "top-level" definitions (like a method or global function) in the first place, so I guess this translates to "use vareverywhere 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.

当然,要求的和推荐的不是一回事;在实践中,约定似乎是顶级定义总是具有类型声明,而本地化定义则忽略了类型声明。这似乎在定义作为一个整体的可读性的明确性之间取得了良好的平衡,与本地“帮助程序”或“临时”定义的可读性的简洁性形成鲜明对比。如果我理解正确,首先您不能使用var“顶级”定义(如方法或全局函数),所以我想这var在 C# 世界中可以转化为“随处使用”。当然,键入“ int”与“ var”的击键次数相同,但大多数示例会比这更长。

回答by yfeldblum

Coming from the land of functional programming, where type-inference rules the day, I use varfor all locals wherever possible.

来自函数式编程的领域,在那里类型推断占主导地位,我var尽可能将其用于所有本地人。

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.

在 Visual Studio 中,如果您想知道任何本地的类型是什么,您所要做的就是将鼠标悬停在它上面。

回答by Ale? Roubí?ek

I tend to use vareverywhere, but my co-workers said stop, it is less readable to us. So I now I use varonly on anonymous types, LINQ queries and where is constructor on right side.

我倾向于在var任何地方使用,但我的同事说停止,它对我们来说可读性较差。所以我现在var只在匿名类型、LINQ 查询和右侧的构造函数中使用。