在与同事讨论了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关键字将解析为该类型名称,并且不会被视为隐式类型局部变量声明的一部分。

其他回答

有时编译器也能比开发人员“更好”地推断出需要什么——至少开发人员不了解他所使用的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

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

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

I don't understand why people start debates like this. It really serves no purpose than to start flame wars at then end of which nothing is gained. Now if the C# team was trying to phase out one style in favor of the other, I can see the reason to argue over the merits of each style. But since both are going to remain in the language, why not use the one you prefer and let everybody do the same. It's like the use of everybody's favorite ternary operator: some like it and some don't. At the end of the day, it makes no difference to the compiler.

这就像和你的兄弟姐妹争论你最喜欢的父母是谁:除非他们离婚了,否则没关系!

对于那些认为var可以节省时间的狂热爱好者来说,它可以减少敲击键盘的次数:

StringBuilder sb = new StringBuilder();

than

var sb = new StringBuilder();

如果你不相信,你可以数数……

19对21

如果有必要我会解释的,但你试试吧……(取决于你的智能感知的当前状态,你可能需要为每一个输入更多)

你能想到的每一种类型都是如此!!

我个人的感觉是,除非在不知道类型的情况下,否则永远不应该使用var,因为它降低了代码中的识别可读性。大脑识别字体的时间比识别一整行字体要长。那些懂机器码和比特的老家伙知道我在说什么。大脑是并行处理的,当你使用var时,你强迫它序列化它的输入。为什么会有人想让自己的大脑更努力地工作呢?这就是电脑的作用。