在与同事讨论了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 per say是一个可怕的语言特性,因为我每天都在Jeff Yates描述的代码中使用它。实际上,我几乎每次使用var都是因为泛型会导致一些极其冗长的代码。我活在冗长的代码中,但是泛型太过分了。

也就是说,我(显然……)认为var被滥用的时机已经成熟。如果在一个方法中,代码超过20行,并且到处都是vars,那么维护很快就会变成一场噩梦。此外,在教程中使用var是违背直觉的,在我的书中是一个大禁忌。

另一方面,var是一个“简单”的特性,新程序员会抓住并喜欢它。然后,在几分钟/几小时/几天内,当他们开始触及极限时,遇到了巨大的障碍。为什么我不能从函数中返回var这类问题。此外,向强类型语言添加伪动态类型很容易让新开发人员感到困惑。从长远来看,我认为var关键字实际上会让新程序员更难学习c#。

也就是说,作为一个有经验的程序员,我确实使用var,主要是在处理泛型(显然是匿名类型)时。我相信var将会是c#中最被滥用的特性之一。

其他回答

在大多数情况下,只是输入它更简单——想象一下

var sb = new StringBuilder();

而不是:

StringBuilder sb = new StringBuilder();

有时它是必需的,例如:匿名类型,比如。

var stuff = new { Name = "Me", Age = 20 };

我个人喜欢使用它,尽管它会降低代码的可读性和可维护性。

我想这取决于你的看法。我个人从来没有因为var“误用”而理解一段代码有任何困难,我的同事和我都经常使用它。(我同意智能感知在这方面是一个巨大的帮助。)我欢迎它作为一种消除重复性麻烦的方法。

毕竟,如果语句像

var index = 5; // this is supposed to be bad

var firstEligibleObject = FetchSomething(); // oh no what type is it
                                            // i am going to die if i don't know

如果真的无法处理,没有人会使用动态类型语言。

我广泛使用var。有人批评这降低了代码的可读性,但没有证据支持这种说法。

Admittedly, it may mean that it's not clear what type we are dealing with. So what? This is actually the point of a decoupled design. When dealing with interfaces, you are emphatically not interested in the type a variable has. var takes this much further, true, but I think that the argument remains the same from a readability point of view: The programmer shouldn't actually be interested in the type of the variable but rather in what a variable does. This is why Microsoft also calls type inference “duck typing.”

当我用var声明变量时,它会做什么呢?简单,智能感知让它做什么它就做什么。任何关于c#的推理都忽略了IDE,这是不现实的。实际上,每个c#代码都是在支持智能感知的IDE中编写的。

如果我使用了一个var声明的变量,并对变量的用途感到困惑,那么我的代码就有根本性的问题。Var不是原因,它只是使症状可见。不要责怪送信的人。

现在,c#团队发布了一个编码指南,声明var应该只用于捕获创建匿名类型的LINQ语句的结果(因为在这里,我们没有真正的替代var的方法)。去他的。只要c#团队没有给我一个合理的论证,我就会忽略它,因为在我的专业和个人观点中,这纯粹是胡扯。(抱歉;我找不到相关指南的链接。)

Actually, there are some (superficially) good explanations on why you shouldn't use var but I still believe they are largely wrong. Take the example of “searchabililty”: the author claims that var makes it hard to search for places where MyType is used. Right. So do interfaces. Actually, why would I want to know where the class is used? I might be more interested in where it is instantiated and this will still be searchable because somewhere its constructor has to be invoked (even if this is done indirectly, the type name has to be mentioned somewhere).

这并不坏,这更多的是一种风格上的东西,往往是主观的。当你使用var或不使用var时,它会增加不一致性。

另一个值得关注的情况是,在下面的调用中,你不能仅通过查看CallMe返回的代码来判断类型:

var variable = CallMe();

这是我对var的主要抱怨。

当我在方法中声明匿名委托时,我使用var,在某种程度上var看起来比我使用Func更干净。考虑下面的代码:

var callback = new Func<IntPtr, bool>(delegate(IntPtr hWnd) {
   ...
});

编辑:根据Julian的输入更新最后一个代码样例

这两种说法都不是绝对正确的;Var对可读性既有正面影响,也有负面影响。在我看来,var应该在以下情况之一成立时使用:

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

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