在与同事讨论了c# 3中var关键字的使用后,我想知道人们对通过var适当使用类型推断的看法是什么?

例如,我很懒地在有问题的情况下使用var,例如:-

foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.

var更合法的用法如下:-

var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.

有趣的是,LINQ似乎是一个灰色区域,例如:-

var results = from r in dataContext.SomeTable
              select r; // Not *entirely clear* what results will be here.

结果很明显,因为它将是一个实现IEnumerable的类型,但它并不完全明显,与var声明一个新对象的方式相同。

当涉及到对象的LINQ时,情况就更糟了,例如:-

var results = from item in someList
              where item != 3
              select item;

这并不比等价的foreach(var item in someList){//…}相当于。

这里有一个关于类型安全的真正问题——例如,如果我们将该查询的结果放在一个接受IEnumerable<int>和IEnumerable<double>的重载方法中,调用者可能会无意中传入错误的类型。

Var确实保持强类型,但问题是,在定义中不立即显示类型是否危险,当重载意味着当你无意中将错误的类型传递给方法时,编译器可能不会发出错误,这种情况会被放大。


当前回答

来自c#团队的高级软件设计工程师Eric Lippert:

为什么引入var关键字?

There are two reasons, one which exists today, one which will crop up in 3.0. The first reason is that this code is incredibly ugly because of all the redundancy: Dictionary<string, List<int>> mylists = new Dictionary<string, List<int>>(); And that's a simple example – I've written worse. Any time you're forced to type exactly the same thing twice, that's a redundancy that we can remove. Much nicer to write var mylists = new Dictionary<string,List<int>>(); and let the compiler figure out what the type is based on the assignment. Second, C# 3.0 introduces anonymous types. Since anonymous types by definition have no names, you need to be able to infer the type of the variable from the initializing expression if its type is anonymous.

我特别强调。整篇文章,c# 3.0仍然是静态类型的,真的!,以及随后的系列相当不错。

这就是var的作用。其他用途可能就没这么好用了。任何与JScript、VBScript或动态类型的比较都是胡扯。再次注意,var是为了使某些其他特性在. net中工作而必需的。

其他回答

当然,int很简单,但当变量的类型是IEnumerable<MyStupidLongNamedGenericClass<int, string>>时,var会让事情变得更简单。

@Keith -

在你们的比较中 IEnumerable < int > IEnumerable<double>你不需要 担心——如果你传递了错误的类型 您的代码无论如何都无法编译。

这并不完全正确——如果一个方法同时重载到IEnumerable<int>和IEnumerable<double>,那么它可能会无声地将意外推断的类型(由于程序中的其他一些更改)传递给错误的重载,从而导致不正确的行为。

我想问题是这种情况出现的可能性有多大!

我猜部分问题是var给给定的声明增加了多少混乱——如果不清楚某个东西是什么类型(尽管它是强类型的,编译器完全理解它是什么类型),有人可能会掩盖一个类型安全错误,或者至少需要更长的时间来理解一段代码。

我尽可能使用var。

如果你的代码写得好,局部变量的实际类型并不重要(例如,良好的变量名,注释,清晰的结构等)。

我不认为var per say是一个可怕的语言特性,因为我每天都在Jeff Yates描述的代码中使用它。实际上,我几乎每次使用var都是因为泛型会导致一些极其冗长的代码。我活在冗长的代码中,但是泛型太过分了。

也就是说,我(显然……)认为var被滥用的时机已经成熟。如果在一个方法中,代码超过20行,并且到处都是vars,那么维护很快就会变成一场噩梦。此外,在教程中使用var是违背直觉的,在我的书中是一个大禁忌。

另一方面,var是一个“简单”的特性,新程序员会抓住并喜欢它。然后,在几分钟/几小时/几天内,当他们开始触及极限时,遇到了巨大的障碍。为什么我不能从函数中返回var这类问题。此外,向强类型语言添加伪动态类型很容易让新开发人员感到困惑。从长远来看,我认为var关键字实际上会让新程序员更难学习c#。

也就是说,作为一个有经验的程序员,我确实使用var,主要是在处理泛型(显然是匿名类型)时。我相信var将会是c#中最被滥用的特性之一。

这是个人品味的问题。当您习惯了动态类型的语言后,所有关于变量类型的烦恼都消失了。也就是说,如果你开始喜欢他们(我不确定是不是每个人都可以,但我喜欢)。

c#的var非常酷,因为它看起来像动态类型,但实际上是静态类型——编译器会强制正确使用。

变量的类型并不是那么重要(这在前面已经说过了)。从上下文(它与其他变量和方法的交互)和它的名称来看,它应该相对清晰——不要期望customerList包含int…

我还在等着看我的老板对这件事的看法——我得到了一个全面的“允许”,可以在3.5中使用任何新的结构,但是我们将如何维护呢?