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


当前回答

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

其他回答

令人惊讶的是,到目前为止还没有注意到这一点,但对foreach循环变量使用var是常识。

如果您指定了特定的类型,则可能会有编译器无声地将运行时强制转换插入程序的风险!

foreach (Derived d in listOfBase)
{

上面的代码将被编译。但是编译器会插入一个从Base到Derived的向下转换。因此,如果列表中的任何内容在运行时不是派生的,则存在无效的强制转换异常。类型安全受到损害。隐形演员太可怕了。

排除这种情况的唯一方法是使用var,因此编译器会根据列表的静态类型来确定循环变量的类型。

这纯粹是为了方便。编译器将推断类型(基于右边表达式的类型)。

没有,只是不需要写两次类型名。http://msdn.microsoft.com/en-us/library/bb383973.aspx

如果你很懒,对匿名类型以外的任何类型都使用var,你应该被要求在这些变量的命名中使用匈牙利符号。

var iCounter=0;

生命!

天啊,我真想念VB。

var是c# 3.0和LINQ中为匿名类型引入的占位符。

因此,它允许在一个集合中为更少的列编写LINQ查询。不需要在内存中复制信息,只加载完成你需要做的事情所必需的东西。

var的使用一点也不坏,因为它实际上不是一个类型,但正如在其他地方提到的,它是一个类型的占位符,它是并且必须定义在等式的右边。然后,编译器将用类型本身替换关键字。

即使使用智能感知,当一个类型的名称很长时,它也特别有用。只需要写var,然后实例化它。之后阅读您的代码的其他程序员将很容易理解您在做什么。

就像使用

public object SomeObject { get; set; }

而不是:

public object SomeObject {
    get {
        return _someObject;
    } 
    set {
        _someObject = value;
    }
}
private object _someObject;

每个人都知道属性在做什么,就像每个人都知道var关键字在做什么一样,这两个例子都倾向于通过简化它来简化可读性,并使程序员更容易编写有效的代码。