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


当前回答

这纯粹是为了方便。编译器将推断类型(基于右边表达式的类型)。

其他回答

我们采用了“为人编写代码,而不是为机器编写代码”的理念,基于这样的假设:在维护模式中花费的时间要比在新的开发模式中花费的时间长好几倍。

对我来说,这就排除了编译器“知道”变量是什么类型的说法——当然,你不可能第一次就写出无效的代码,因为编译器会阻止你的代码编译,但是当下一个开发人员在6个月的时间里阅读代码时,他们需要能够推断出变量做得正确或不正确的地方,并快速确定问题的原因。

因此,

var something = SomeMethod();

在我们的编码标准中是不合法的,但在我们的团队中鼓励这样做,因为它增加了可读性:

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
   DoWork( item ); 
}

对于LINQ,使用var的另一个很好的理由是编译器可以更优化查询。

如果你使用一个静态列表来存储结果,它将在你分配给列表的地方执行,但是使用var,它可以潜在地将原始查询与代码中后面的查询合并,从而对数据库进行更优化的查询。

我有一个例子,我在第一个查询中提取了一些数据,然后循环遍历并请求更多数据以打印出一个表。

LINQ合并了这些,所以第一个只提取id。

然后在循环中,它添加了一个我没有在那里做的额外连接来获取我包含在原始数据中的数据。

经过测试,这种方法效率更高。

如果我们没有使用var,它就会像我们写的那样进行查询。

大多数人忽视的是:

var something = new StringBuilder(); 

通常打字的速度没有

StringBuilder something = KEY'TAB'();

我认为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。

var是处理匿名类型的方法,无论是否来自LINQ语句。任何其他用途在很大程度上取决于谁将阅读您的代码以及有哪些指导方针。

如果你是唯一的观众,或者你的观众对使用var很熟悉,或者非常熟悉你的代码,那么我想这没有关系。如果你像这样使用:var s = new SqlConnection(),那么这在很大程度上无关紧要,可能会提高代码的可读性。如果人们不太挑剔,他们可以做一些工作来了解不明显的类型(这在大多数情况下是不需要的,你在下面的语句中如何使用它通常会解释一切),那么它是好的。

但是如果你有挑剔的,思想封闭的队友,他们喜欢抱怨,或者如果你公司的设计准则特别禁止在类型不明显时使用var,那么你很可能会遇到强烈的反对。

如果使用var会让你的代码难以阅读,你可能会因为使用var而受到伤害,即使这可能是你的应用程序设计的问题。

如果var引入了歧义(有点像你的IEnumerable/IEnumerable例子),不要使用它,而是显式地使用它。但var确实有它的便利,在某些情况下,恕我直言,它甚至可以通过减少混乱来提高可读性。