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


当前回答

摘自CodingHorror关于这一问题的文章:


不幸的是,你和其他人都错了。虽然我同意你的观点,冗余不是一件好事,但解决这个问题的更好方法应该是这样做:

MyObject m = new();

或者如果你传递参数:

Person p = new("FirstName", "LastName ");

在创建新对象时,编译器从左边推断类型,而不是右边。这比“var”有其他优点,因为它也可以在字段声明中使用(还有其他一些领域,它也可能有用,但我不会在这里讨论)。

最后,这并不是为了减少冗余。不要误解我,“var”在c#中对于匿名类型/投影是非常重要的,但是这里的使用是非常错误的(我已经说了很长很长一段时间了),因为你混淆了正在使用的类型。输入两次太频繁了,但是声明0次就太少了。

2008年6月20日上午08:00,c#mvp


我想如果你主要关心的是必须少打字——那么没有任何争论会动摇你使用它。

如果你只是一个查看代码的人,那么谁在乎呢?否则,在这种情况下:

var people = Managers.People

没关系,但在这种情况下:

var fc = Factory.Run();

它使我的大脑从代码的“英文”开始形成的任何即时类型推断短路。

否则,就用你最好的判断和编程“礼貌”来对待那些可能不得不为你的项目工作的人。

其他回答

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

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

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

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

取决于,它使代码看起来“更干净”,但同意它使它更难以读…

因冗余原因删除。

var仍然被初始化为正确的变量类型——编译器只是从上下文推断它。正如您所提到的,var使我们能够存储对匿名类实例的引用——但它也使更改代码变得更容易。例如:

// If you change ItemLibrary to use int, you need to update this call
byte totalItemCount = ItemLibrary.GetItemCount();

// If GetItemCount changes, I don't have to update this statement.
var totalItemCount = ItemLibrary.GetItemCount();

是的,如果很难从变量的名称和用法中确定变量的类型,那么无论如何都要显式声明它的类型。

“关于我的品味,你唯一能说的就是它过时了,假以时日,你也会过时的。”托尔金。

你不需要写出类型名,这不会降低性能,因为类型是在编译时解析的。