在与同事讨论了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#中var的用法。它仍然是强类型,不像VB的变体类型,所以使用或不使用它对性能没有影响。

因为它对最终编译的代码没有影响,所以它实际上是一个设计器的选择。就我个人而言,我不使用它,因为我发现定义了完整类型的代码更容易阅读,但我可以想象,几年后,完整类型声明将像现在的匈牙利符号一样被看待——额外的类型与默认情况下智能感知提供给我们的信息相比并没有真正的好处。

其他回答

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

他们说去吧,我就用了。

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

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

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

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

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

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

@aku:代码审查就是一个例子。另一个例子是重构场景。

基本上我不想用我的鼠标去打字。它可能不可用。

Apart from readability concerns, there is one real issue with the use of 'var'. When used to define variables that are assigned to later in the code it can lead to broken code if the type of the expression used to initialize the variable changes to a narrower type. Normally it would be safe to refactor a method to return a narrower type than it did before: e.g. to replace a return type of 'Object' with some class 'Foo'. But if there is a variable whose type is inferred based on the method, then changing the return type will mean that this variable can longer be assigned a non-Foo object:

var x = getFoo(); // Originally declared to return Object
x = getNonFoo();

所以在这个例子中,改变getFoo的返回类型会使getNonFoo的赋值变为非法。

如果getFoo和它的所有用途都在同一个项目中,这不是什么大问题,但如果getFoo在一个库中供外部项目使用,如果他们像这样使用'var',你就不能确保缩小返回类型不会破坏某些用户的代码。

正是由于这个原因,当我们在Curl编程语言中添加类似的类型推断特性(在Curl中称为'def')时,我们阻止了对使用这种语法定义的变量的赋值。

在大多数情况下,只是输入它更简单——想象一下

var sb = new StringBuilder();

而不是:

StringBuilder sb = new StringBuilder();

有时它是必需的,例如:匿名类型,比如。

var stuff = new { Name = "Me", Age = 20 };

我个人喜欢使用它,尽管它会降低代码的可读性和可维护性。