在与同事讨论了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很有用。例如,我昨天需要一个类似于此的数据结构。您喜欢哪种表示法?

Dictionary<string, Dictionary<string, List<MyNewType>>> collection = new Dictionary<string, Dictionary<string, List<MyNewType>>>();

or

var collection = new Dictionary<string, Dictionary<string, List<MyNewType>>>();

请注意,在本例中使用var几乎不会引起歧义。然而,有时候这并不是一个好主意。例如,如果我像下面这样使用var,

var value= 5;

当我可以只写真正的类型,并消除任何歧义5应该如何表示。

double value = 5;

其他回答

我尽可能使用var。

如果你的代码写得好,局部变量的实际类型并不重要(例如,良好的变量名,注释,清晰的结构等)。

Var还不错。记住这一点。Var还不错。重复一遍。Var还不错。记住这一点。Var还不错。重复一遍。

如果编译器足够聪明,可以从上下文中找出类型,那么您也可以。你不需要在申报时把它写下来。而智能感知让这变得更加不必要。

Var还不错。记住这一点。Var还不错。重复一遍。Var还不错。记住这一点。Var还不错。重复一遍。

来自Essential LINQ:

除非绝对必要,否则最好不要显式声明范围变量的类型。例如,下面的代码编译干净,但是编译器可以在没有正式声明的情况下推断出类型:

List<string> list = new List<string> { "LINQ", "query", "adventure" };
var query = from string word in list
      where word.Contains("r")
      orderby word ascending
      select word;

显式声明range变量的类型会强制对LINQ Cast操作符进行幕后调用。此调用可能会产生意想不到的结果,并可能会损害性能。如果您在LINQ查询中遇到性能问题,像这里所示的强制转换可能是开始寻找罪魁祸首的一个地方。(此规则的一个例外是当您使用非泛型Enumerable时,在这种情况下您应该使用强制转换。)

第一。

Var不是一个类型,也不是什么特殊的特性(比如c# 4.0的动态特性)。它只是一个语法糖。你要求编译器通过右边的表达式来推断类型。唯一需要的地方是匿名类型。

我不认为使用var既好又坏,这是一种编码风格。我个人不使用它,但我不介意其他团队成员使用它。

Apart from readability concerns, there is one real issue with the use of 'var'. When used to define variables that are assigned to later in the code it can lead to broken code if the type of the expression used to initialize the variable changes to a narrower type. Normally it would be safe to refactor a method to return a narrower type than it did before: e.g. to replace a return type of 'Object' with some class 'Foo'. But if there is a variable whose type is inferred based on the method, then changing the return type will mean that this variable can longer be assigned a non-Foo object:

var x = getFoo(); // Originally declared to return Object
x = getNonFoo();

所以在这个例子中,改变getFoo的返回类型会使getNonFoo的赋值变为非法。

如果getFoo和它的所有用途都在同一个项目中,这不是什么大问题,但如果getFoo在一个库中供外部项目使用,如果他们像这样使用'var',你就不能确保缩小返回类型不会破坏某些用户的代码。

正是由于这个原因,当我们在Curl编程语言中添加类似的类型推断特性(在Curl中称为'def')时,我们阻止了对使用这种语法定义的变量的赋值。