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


当前回答

在转换到3.0和3.5框架之后,我了解了这个关键字,并决定尝试一下。在提交任何代码之前,我意识到它似乎是向后的,就像回到ASP语法一样。所以我决定戳一下高层,看看他们怎么想。

他们说去吧,我就用了。

也就是说,我避免在类型需要一些调查的地方使用它,就像这样:

var a = 公司。获取记录();

现在它可能只是一个个人的事情,但我立即不能看,并确定如果它是一个记录对象的集合或一个字符串数组表示记录的名称。无论哪种情况,我认为显式声明在这种情况下是有用的。

其他回答

这两种说法都不是绝对正确的;Var对可读性既有正面影响,也有负面影响。在我看来,var应该在以下情况之一成立时使用:

类型是匿名的(好吧,这里没有任何选择,因为在这种情况下它必须是var) 根据指定的表达式,类型是明显的(即var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating())

Var没有性能影响,因为它是语法糖;一旦编译成IL,编译器就会推断出类型并定义它;没有什么动态的东西。

取决于,它使代码看起来“更干净”,但同意它使它更难以读…

您可以让编译器(以及接下来维护代码的人员)从初始化式赋值的右边推断类型。如果这种推断是可能的,编译器可以这样做,从而节省了您的一些输入。

如果这个推断对那个可怜的家伙来说很容易,那么你没有伤害到任何东西。如果推断很难,那么作为一般规则,您已经使代码更难维护 我不会这么做的。

Lastly, if you intended the type to be something particular, and your initializer expression actually has a different type, using var means it will be harder for you to find the induced bug. By explicitly telling the compiler what you intend the type to be, when the type isn't that, you would get an immediate diagnostic. By sluffing on the type declaration and using "var", you won't get an error on the initialization; instead, you'll get a type error in some expression that uses the identifier assigned by the var expression, and it will be harder to understand why.

寓意是,要谨慎使用var;您通常不会给您自己或您的下游维护人员带来很多好处。并希望他的理由是一样的,这样你就不会因为他认为使用var很容易而猜测他的意图。在编写一个具有较长生命周期的系统时,优化输入量是一个错误。

我认为var的使用应该与明智选择的变量名称相结合。

我在foreach语句中使用var没有问题,前提是它不是这样的:

foreach (var c in list) { ... }

如果是这样的话:

foreach (var customer in list) { ... }

... 这样,阅读代码的人就更有可能理解什么是“列表”。如果您可以控制列表变量本身的名称,那就更好了。

这同样适用于其他情况。这是非常无用的:

var x = SaveFoo(foo);

... 但这是有道理的:

var saveSucceeded = SaveFoo(foo);

各有各的,我想。我发现自己这样做,简直是疯了:

var f = (float)3;

我需要一个12步的var程序。我叫Matt,我(ab)使用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中工作而必需的。