在与同事讨论了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是否比在一个类中拥有成员变量或在一个方法中定义在可见屏幕区域之外的局部变量更难阅读。

如果你有一行代码,比如

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Is比以下更容易或更难读:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

其他回答

当然,int很简单,但当变量的类型是IEnumerable<MyStupidLongNamedGenericClass<int, string>>时,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,我就不必这样做。

@Keith -

在你们的比较中 IEnumerable < int > IEnumerable<double>你不需要 担心——如果你传递了错误的类型 您的代码无论如何都无法编译。

这并不完全正确——如果一个方法同时重载到IEnumerable<int>和IEnumerable<double>,那么它可能会无声地将意外推断的类型(由于程序中的其他一些更改)传递给错误的重载,从而导致不正确的行为。

我想问题是这种情况出现的可能性有多大!

我猜部分问题是var给给定的声明增加了多少混乱——如果不清楚某个东西是什么类型(尽管它是强类型的,编译器完全理解它是什么类型),有人可能会掩盖一个类型安全错误,或者至少需要更长的时间来理解一段代码。

静态类型是关于契约的,而不是源代码。这里的想法是需要将静态信息放在“应该”是一个小方法的单行上。一般指南建议每个方法不要超过25行。

如果一个方法足够大,以至于您无法跟踪该方法中的单个变量,那么您做错了其他事情,这将使任何对var的批评相形见绌。

实际上,var的一个重要论点是它可以使重构更简单,因为你不再需要担心你的声明过于严格(例如,当你应该使用IList<>或IEnumerable<>时,你使用了List<>)。您仍然需要考虑新的方法签名,但至少不必返回并更改声明来匹配。

这是个人品味的问题。当您习惯了动态类型的语言后,所有关于变量类型的烦恼都消失了。也就是说,如果你开始喜欢他们(我不确定是不是每个人都可以,但我喜欢)。

c#的var非常酷,因为它看起来像动态类型,但实际上是静态类型——编译器会强制正确使用。

变量的类型并不是那么重要(这在前面已经说过了)。从上下文(它与其他变量和方法的交互)和它的名称来看,它应该相对清晰——不要期望customerList包含int…

我还在等着看我的老板对这件事的看法——我得到了一个全面的“允许”,可以在3.5中使用任何新的结构,但是我们将如何维护呢?