在与同事讨论了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确实保持强类型,但问题是,在定义中不立即显示类型是否危险,当重载意味着当你无意中将错误的类型传递给方法时,编译器可能不会发出错误,这种情况会被放大。


当前回答

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

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

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

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

其他回答

来自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中工作而必需的。

有人不喜欢批评var..所有答案downmodded..哦. .

@Jon Limjap: 我知道。:)我的意思是可读性被降级了,就像在VB6一样。我不喜欢依靠智能感知来确定给定变量的类型。我希望能单独用源代码求出它。

命名惯例也没用——我已经用好名字了。我们要回到前缀时代吗?

当我开始使用var关键字时,我也有同样的担忧。 然而,随着时间的推移,我已经习惯了它,不打算回到显式变量类型。 Visual Studio的编译器\智能感知在使隐式类型变量的工作更容易方面做得非常好。

我认为遵循正确的命名约定可以帮助您更好地理解代码,而不是显式键入。

这似乎是类似于“我应该在变量名中使用前缀吗?”这样的问题。 坚持使用好的变量名,让编译器考虑变量类型。

“关于我的品味,你唯一能说的就是它过时了,假以时日,你也会过时的。”托尔金。

令人惊讶的是,到目前为止还没有注意到这一点,但对foreach循环变量使用var是常识。

如果您指定了特定的类型,则可能会有编译器无声地将运行时强制转换插入程序的风险!

foreach (Derived d in listOfBase)
{

上面的代码将被编译。但是编译器会插入一个从Base到Derived的向下转换。因此,如果列表中的任何内容在运行时不是派生的,则存在无效的强制转换异常。类型安全受到损害。隐形演员太可怕了。

排除这种情况的唯一方法是使用var,因此编译器会根据列表的静态类型来确定循环变量的类型。