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


当前回答

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

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

其他回答

Var,在我看来,在c#中是一个很好的东西。任何这样类型的变量仍然是强类型的,但是它从赋值函数的右边得到它的类型。因为类型信息在右侧可用,在大多数情况下,也必须在左侧输入它是不必要的和过于冗长的。我认为这在不降低类型安全性的情况下显著提高了可读性。

From my perspective, using good naming conventions for variables and methods is more important from a readability perspective than explicit type information. If I need the type information, I can always hover over the variable (in VS) and get it. Generally, though, explicit type information shouldn't be necessary to the reader. For the developer, in VS you still get Intellisense, regardless of how the variable is declared. Having said all of that, there may still be cases where it does make sense to explicitly declare the type -- perhaps you have a method that returns a List<T>, but you want to treat it as an IEnumerable<T> in your method. To ensure that you are using the interface, declaring the variable of the interface type can make this explicit. Or, perhaps, you want to declare a variable without an initial value -- because it immediately gets a value based on some condition. In that case you need the type. If the type information is useful or necessary, go ahead and use it. I feel, though, that typically it isn't necessary and the code is easier to read without it in most cases.

第一。

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

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

我仍然认为var在某些情况下可以使代码更具可读性。如果我有一个带有Orders属性的Customer类,我想把它赋值给一个变量,我只需要这样做:

var orders = cust.Orders;

我不在乎顾客。Orders是IEnumerable<Order>, ObservableCollection<Order>或BindingList<Order> -我想要的只是将该列表保存在内存中,以便稍后对其进行迭代或获取其计数或其他内容。

将上述声明与:

ObservableCollection<Order> orders = cust.Orders;

对我来说,类型名只是噪音。如果我回头决定改变客户的类型。沿着轨道的订单(从ObservableCollection<Order>到IList<Order>),然后我也需要改变声明-如果我在第一个地方使用var,我就不必这样做。

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

他们说去吧,我就用了。

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

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

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

将它用于匿名类型—这就是它存在的目的。其他的都是徒劳无功。像许多使用C长大的人一样,我习惯于查看类型声明的左侧。除非迫不得已,我是不会看右边的。在任何旧的声明中使用var都让我一直这样做,我个人觉得不舒服。

Those saying 'it doesn't matter, use what you're happy with' are not seeing the whole picture. Everyone will pick up other people's code at one point or another and have to deal with whatever decisions they made at the time they wrote it. It's bad enough having to deal with radically different naming conventions, or - the classic gripe - bracing styles, without adding the whole 'var or not' thing into the mix. The worst case will be where one programmer didn't use var and then along comes a maintainer who loves it, and extends the code using it. So now you have an unholy mess.

标准是一件好事,因为它们意味着你更有可能捡起随机代码,并能够快速地理解它。不同的东西越多,就越难。而转移到“无处不在的var”风格会有很大的不同。

I don't mind dynamic typing, and I don't mind implict typing - in languages that are designed for them. I quite like Python. But C# was designed as a statically explicitly-typed language and that's how it should stay. Breaking the rules for anonymous types was bad enough; letting people take that still further and break the idioms of the language even more is something I'm not happy with. Now that the genie is out of the bottle, it'll never go back in. C# will become balkanised into camps. Not good.