在与同事讨论了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而不是显式类型使重构更容易(因此我必须反驳前面的帖子,他们的意思是它没有区别,或者它纯粹是“语法糖”)。

您可以更改方法的返回类型,而无需更改调用此方法的每个文件。想象一下

...
List<MyClass> SomeMethod() { ... }
...

就像这样

...
IList<MyClass> list = obj.SomeMethod();
foreach (MyClass c in list)
  System.Console.WriteLine(c.ToString());
...

如果您希望重构SomeMethod()以返回IEnumerable<MySecondClass>,则必须在使用该方法的每个地方更改变量声明(也在foreach中)。

如果你写

...
var list = obj.SomeMethod();
foreach (var element in list)
  System.Console.WriteLine(element.ToString());
...

相反,你不需要改变它。

其他回答

如果你知道类型,就使用类型。 如果你不知道哪种类型,为什么不呢? 如果您不知道类型,也没关系——您已经找到了唯一有效的用法。

我很抱歉,但如果你能做到的最好的是“它使代码全部对齐”,那不是一个好答案。找一种不同的方式来格式化代码。

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

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

我认为人们不理解var关键字。 他们把它和Visual Basic / JavaScript关键字搞混了, 这完全是另一回事。

许多人认为var关键字意味着 弱类型(或动态类型),而实际上c#是并保持强类型。

如果你在javascript中考虑这个:

var something = 5;

你可以:

something = "hello";

在c#中,编译器会从第一条语句中推断出类型, 导致“int”类型的东西,因此会产生第二条语句 在异常中。

人们只需要明白,使用var关键字并不意味着 动态类型,然后决定var关键字的使用程度, 知道它对于将要编译的内容绝对没有区别。

当然var关键字的引入是为了支持匿名类型, 但如果你看这个:

LedDeviceController controller = new LedDeviceController("172.17.0.1");

这是非常非常冗长的,我相信这是一样可读的,如果不是更多:

var controller = new LedDeviceController("172.17.0.1");

结果是完全相同的,所以是的,我在我的代码中使用它

更新:

也许,只是也许……他们应该用另一个关键词, 那我们就不会有这样的讨论了……也许是“推断”关键字而不是“var”

我不明白这有什么大不了的。

var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!

你仍然对“某事”有完全的智能感知,对于任何不明确的情况,你都有单元测试,对吗?(是吗?)

它不是varchar,也不是dim,当然也不是动态或弱类型。它像这样阻止疯狂的人:

List<somethinglongtypename> v = new List<somethinglongtypename>();

把这些杂乱的思想归纳为:

var v = new List<somethinglongtypename>();

不错,但不如:

v = List<somethinglongtypename>();

但这就是布的作用。

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

var orders = cust.Orders;

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

将上述声明与:

ObservableCollection<Order> orders = cust.Orders;

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