在与同事讨论了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使我们能够存储对匿名类实例的引用——但它也使更改代码变得更容易。例如:

// 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();

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

其他回答

我在以下情况下使用var:

当我不得不(结果是匿名的) 当类型与代码在同一行时,例如: var emp = new Employee();

很明显,我们需要一个Employee对象(因为我们正在创建一个新的Employee对象),那么如何呢

Employee emp = new Employee() any more obvious?

当类型无法推断时,我不使用var。

var emp = GetEmployee();

因为返回类型不是很明显(是在Employee对象上,还是在IEmployee对象上,还是在与Employee对象完全没有关系的对象上,等等?)

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

var iCounter=0;

生命!

天啊,我真想念VB。

@erlando,

谈到重构,通过将新类型的实例分配给一个变量而不是在多个地方更改它来更改变量类型似乎要容易得多,不是吗?

至于代码审查,我认为var关键字没有大问题。在代码审查期间,我更喜欢检查代码逻辑而不是变量类型。当然,可能会有开发人员可以使用不合适的类型的情况,但我认为这种情况的数量是如此之少,它不会成为我停止使用var关键字的原因。

我重复一下我的问题。为什么变量类型对您很重要?

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

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,我也必须不断改变左边声明的类型。我知道这是小事,但它非常方便。

为什么var不应该仅仅被用作“输入快捷方式”,而应该被用于它们主要设计的场景:Resharper(至少v4.5)如果一个类型被表示为var,就无法找到它的用法。这在重构或分析源代码时可能是一个真正的问题。