在与同事讨论了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();

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

其他回答

你最可能需要它的时候是匿名类型(100%需要);但它也避免了琐碎案件的重复,IMO使界限更加清晰。对于简单的初始化,我不需要看到类型两次。

例如:

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();

(请不要编辑上面的hscroll -它有点证明了这一点!!)

vs:

var data = new Dictionary<string, List<SomeComplexType<int>>>();

然而,在某些情况下,这是一种误导,并可能导致错误。如果原始变量和初始化类型不相同,请谨慎使用var。例如:

static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}

// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);

我认为var的使用应该与明智选择的变量名称相结合。

我在foreach语句中使用var没有问题,前提是它不是这样的:

foreach (var c in list) { ... }

如果是这样的话:

foreach (var customer in list) { ... }

... 这样,阅读代码的人就更有可能理解什么是“列表”。如果您可以控制列表变量本身的名称,那就更好了。

这同样适用于其他情况。这是非常无用的:

var x = SaveFoo(foo);

... 但这是有道理的:

var saveSucceeded = SaveFoo(foo);

各有各的,我想。我发现自己这样做,简直是疯了:

var f = (float)3;

我需要一个12步的var程序。我叫Matt,我(ab)使用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>();

但这就是布的作用。

在转换到3.0和3.5框架之后,我了解了这个关键字,并决定尝试一下。在提交任何代码之前,我意识到它似乎是向后的,就像回到ASP语法一样。所以我决定戳一下高层,看看他们怎么想。

他们说去吧,我就用了。

也就是说,我避免在类型需要一些调查的地方使用它,就像这样:

var a = 公司。获取记录();

现在它可能只是一个个人的事情,但我立即不能看,并确定如果它是一个记录对象的集合或一个字符串数组表示记录的名称。无论哪种情况,我认为显式声明在这种情况下是有用的。

它可以使代码更简单、更短,特别是对于复杂的泛型类型和委托。

此外,它使变量类型更容易更改。