在与同事讨论了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的反感说明了。net中双语的重要性。对于那些使用过VB . net的c#程序员来说,var的优势是显而易见的。标准的c#声明:

List<string> whatever = new List<string>();

在VB .NET中,相当于键入:

Dim whatever As List(Of String) = New List(Of String)

不过,在VB . net中没有人这样做。这样做是愚蠢的,因为从。net的第一个版本开始,你就可以这样做了…

Dim whatever As New List(Of String)

...它创建变量并在一个相当紧凑的行中初始化它。啊,但是如果你想要一个IList<string>,而不是一个List<string>?在VB .NET中,这意味着你必须这样做:

Dim whatever As IList(Of String) = New List(Of String)

就像你在c#中必须做的那样,显然不能使用var:

IList<string> whatever = new List<string>();

如果您需要不同的类型,它可以是。但优秀编程的基本原则之一是减少冗余,这正是var所做的。

其他回答

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

第一。

Var不是一个类型,也不是什么特殊的特性(比如c# 4.0的动态特性)。它只是一个语法糖。你要求编译器通过右边的表达式来推断类型。唯一需要的地方是匿名类型。

我不认为使用var既好又坏,这是一种编码风格。我个人不使用它,但我不介意其他团队成员使用它。

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

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

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

我不使用var,因为它违背了c#的根- C/ c++ /Java。尽管这是一个编译器技巧,但它使语言感觉不那么强类型。也许20多年的C语言已经在我们(反变量的人)的头脑中根深蒂固了,我们应该在等号的左右两边都有类型。

话虽如此,我可以看到它对于长泛型集合定义和长类名(如codinghorror.com示例)的优点,但在其他地方,如string/int/bool,我真的看不出这一点。特别是

foreach (var s in stringArray)
{

}

节省3个字符!

对我来说,主要的烦恼是无法看到var代表方法调用的类型,除非你将鼠标悬停在方法上或F12它。

没有,只是不需要写两次类型名。http://msdn.microsoft.com/en-us/library/bb383973.aspx