在与同事讨论了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对可读性既有正面影响,也有负面影响。在我看来,var应该在以下情况之一成立时使用:

类型是匿名的(好吧,这里没有任何选择,因为在这种情况下它必须是var) 根据指定的表达式,类型是明显的(即var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating())

Var没有性能影响,因为它是语法糖;一旦编译成IL,编译器就会推断出类型并定义它;没有什么动态的东西。

其他回答

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

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

foreach (Derived d in listOfBase)
{

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

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

它当然可以让事情变得更简单,从我昨天写的代码来看:

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }

如果没有var,这将是非常冗长的。

附录:花点时间学习具有真正类型推断的语言(例如f#),就会发现编译器在正确获取表达式类型方面是多么出色。这当然意味着我倾向于尽可能多地使用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关键字实际上使代码更具可读性,因为你只是习惯于跳过'var'关键字。当您真的不关心具体类型是什么时,您不需要一直向下滚动来弄清楚代码在做什么。如果我真的需要知道下面的“item”是什么类型,我只需将鼠标悬停在它上面,Visual Studio就会告诉我。换句话说,我更愿意读书

foreach( var item in list ) { DoWork( item ); }

一遍又一遍地

foreach( KeyValuePair<string, double> entry in list ) { DoWork( Item ); }

当我试图消化代码时。我认为这在某种程度上可以归结为个人喜好。在这一点上,我将依赖常识——在重要的方面(安全性、数据库使用、日志记录等)保留强制标准。

-工业。

在测试过程中,我发现自己的代码是这样的:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);

现在,有时,我想看看SomeOtherThing本身包含什么,SomeOtherThing不是CallMethod()返回的相同类型。因为我使用了var,我只是改变了这个:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();

:

var something = myObject.SomeProperty.SomeOtherThing;

如果没有var,我也必须不断改变左边声明的类型。我知道这是小事,但它非常方便。