在与同事讨论了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“类型”,而不是一个显式的类型。关键字var指示编译器从初始化语句右边的表达式推断变量的类型。

// z被编译为int类型

var z = 100;

// s被编译为下面的字符串

var s = "Hello";

// a被编译为int[]

var a = new[] { 0, 1, 2 };

// expr被编译为IEnumerable //或者IQueryable

var expr =
    from c in customers
    where c.City == "London"
    select c;

// anon被编译为匿名类型

var anon = new { Name = "Terry", Age = 34 };

// list被编译为list

var list = new List<int>();

var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.

Var不能在类范围内的字段上使用。

使用var声明的变量不能在初始化表达式中使用。换句话说,这个表达式是合法的:int i = (i = 20);但是这个表达式会产生一个编译时错误:var I = (I = 20);

多个隐式类型变量不能在同一个语句中初始化。

如果一个名为var的类型在作用域中,那么var关键字将解析为该类型名称,并且不会被视为隐式类型局部变量声明的一部分。

其他回答

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

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

foreach (var s in stringArray)
{

}

节省3个字符!

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

如果有人使用var关键字是因为他们不想“找出类型”,那肯定是错误的原因。var关键字不会创建动态类型的变量,编译器仍然需要知道该类型。由于变量总是具有特定的类型,因此如果可能的话,该类型在代码中也应该是明显的。

使用var关键字的理由如下:

在需要的地方,即声明匿名类型的引用。 它使代码更具可读性,即删除重复的声明。

写出数据类型通常会使代码更容易理解。它显示了您正在使用的数据类型,因此您不必通过先弄清楚代码的功能来弄清楚数据类型。

当你将鼠标悬停在“var”上时,VS2008 w/resharper 4.1在工具提示中有正确的输入,所以我认为当你寻找一个类的所有用法时,它应该能够找到这个。

虽然还没有测试它是否这样做。

Var就像儿童读物中的虚线,孩子们必须填满它。除非在这种情况下,编译器会用正确的类型填充它,通常写在=号之后。

有时编译器也能比开发人员“更好”地推断出需要什么——至少开发人员不了解他所使用的api需要什么。

例如-当使用linq时:

示例1

Func<Person, bool> predicate = (i) => i.Id < 10;
IEnumerable<Person> result = table.Where(predicate);

示例2

var predicate = (Person i) => i.Id < 10;
var result = table.Where(predicate);

在上面的代码中-假设一个是使用Linq到Nhibernate或Linq到SQL,示例1将 返回Person对象的整个结果集,然后在客户端进行筛选。 然而,示例2将在服务器上执行查询(例如在Sql server上使用Sql),因为编译器足够聪明,可以计算出Where函数应该采用表达式>而不是Func。

示例1中的结果在返回IEnumerable时也不能在服务器上进一步查询,而在示例2中,编译器可以计算出结果是否应该是IQueryable而不是IEnumerable