当类型已知时,是否有任何技术理由使用或不使用C#中的var?

似乎越来越多的C#代码我读取使用var类型标识符:

foreach (var itemChange in ItemChanges) { //... } 

而不是明确说明类型:

 foreach (ItemChange itemChange in ItemChanges) { //... } 

即使这种类型已知。

我仍在使用后一个显式版本,因为我认为稍后阅读它会更快地了解变量的类型,而不是使用var。

但是有任何技术理由使用其中一个吗?

没有技术原因。 如果在编译时无法推断出类型,那么代码将无法编译。

您说得对,有些情况可能更好地使用显式类型进行可读性,例如

 var obj = SomeMethod(); // what's the type? you'd have to inspect SomeMethod() SomeClass obj = SomeMethod(); // the type is obvious 

但是使用var的其他情况很有意义,例如

 var obj = new SomeClass(); // the type is obvious SomeClass obj = new SomeClass(); // the duplication of type is unnecessary 

不,只是可读性。

一般没有技术原因。 可读性 – 在任一方向 – 是唯一真正的因素。

但是,一个小警告是var将推断变量的静态类型。 如果你想要一个子类或超类类型,你需要自己进行投射。 对于foreach ,如在您的示例中,您通常可以通过使用子类类型声明循环变量来“免费”为您执行向下转换。

经典示例是迭代XML NodeList,您知道它XmlElement的列表,但Nodelist被键入为XmlNode的集合。 当然你可以使用强制转换或as来取回你想要的类型,但这似乎打败了使用类型推断的目的:-)

当然,只要您尝试使用仅适用于XmlElement的节点成员,编译器就会让您知道这一点 – 因此它仍然不是严格意义上的技术差异。


另一件有点烦人的事情是,如果你使用像Resharper这样的工具,那么建议你在每种可能情况下使用var都非常积极。 当它建议你将一个int声明更改为var时,它特别烦人!

但是,除非你关闭这个function,否则你使用var的次数越多,Resharper就会减少“噪音”。

我所知道的唯一技术原因是你可以执行没有var隐式强制转换,例如

 int i = 5; double a = i; // implicit cast with explicit types 

但在这里我更喜欢var因为它使得演员明确; 虽然我不太在乎我在执行表示更改类型转换时所关注的类型:

 var a = (double)i; // explicit cast with implicit types 

但正如你所说,真正的一般原因是可读性。 你需要问自己的问题是为什么你认为确切的具体类型对于可读性很重要? 你总是写Linq查询调用具体类型,例如

 from ItemChange itemChange in ItemChanges // instead of from itemChange in ItemChanges 

同样,你总是调用generics方法的类型参数而不是使用类型推断,例如

 ItemChanges.Select((ItemChange itemChange) => ...); // instead of ItemChanges.Select(itemChange => ...); 

或者你是否乐意让编译器为你做一些工作并让它解决这些类型,而没有明确说明类型信息的“费用”?

如果你对linq和generics方法中的类型推断感到满意,那么你已经做出了一个决定,即你没有在任何地方明确拼写出类型,你可能没有发现你的代码可读性更低结果(事实上,你可能发现了相反的情况)。 所以使用var只是你已经在同一条路上迈出的又一步。

var是一种C#3.0function,仅在匿名类型中是必需的

因为下面的代码

 var v = new { Amount = 108, Message = "Hello" }; 

动态创建一个新的匿名类型,var使用是必需的。 例如,var在Linq中特别有用,其中类型通常是动态创建的。

在任何其他情况下,它只是最终应用的品味问题(它在编译期间得到解决)。 但是对于代码阅读器,我认为“var”在信息类型方面的信息量较少。

不可以。使用var可以提高可读性,反之亦然。

var是一个C#3.x +function,不是吗? 不使用它,您的代码也与其他版本更兼容。

在搜索“ var C# ”时,SO中有很多有趣的问题

在任何给定的程序状态下,除了匿名类型之外,没有技术上的理由使用var。

但是,使用var允许程序在不需要编辑的情况下进行更改。 特定

 public int SomeMethod(){} public List SomeOtherMethod(T parameter); 

然后

 var x = SomeMethod(); var y = SomeOtherMethod(x); 

会工作(而y将是List )。 如果你曾经使用过

 int x = SomeMethod(); List y = SomeOtherMethod(x); 

然后如果SomeMethod()被改为返回long ,那么你必须改变y的定义。

我已经看到这种事情在整个程序中传播,需要数百次更改。 特殊情况是更改数据访问代码以返回ReadOnlyCollection而不是List 。 需要进行如此多的代码更改,我将List所有显式提及更改为var,并且代码永远不需要再次更改。