在与同事讨论了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 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可以使您的代码更具可读性和可理解性。但是,如果使用不当,var也会使您的代码像Perl一样难以阅读和理解。

一个var的好的和坏的用法列表也不会有太大的帮助。这是一个常识问题。更大的问题是可读性和可写性。许多开发者并不关心他们的代码是否具有可读性。他们只是不想打那么多。就我个人而言,我是一个读,写,写的人。

我不认为var per say是一个可怕的语言特性,因为我每天都在Jeff Yates描述的代码中使用它。实际上,我几乎每次使用var都是因为泛型会导致一些极其冗长的代码。我活在冗长的代码中,但是泛型太过分了。

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

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

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

这次讨论有点晚了,但我想补充一点想法。

对于所有反对类型推断的人(因为这就是我们在这里真正谈论的内容),lambda表达式呢?如果坚持始终显式地声明类型(匿名类型除外),那么如何使用lambdas呢?“不要让我使用鼠标悬停”参数如何适用于var而不是lambdas?

更新

我刚刚想到了一个反对“var”的论点,我认为没有人提到过,那就是它“破坏”了“找到所有引用”,这可能意味着(例如)如果你在重构之前检查一个类的使用情况,你会错过类通过var使用的所有地方。

我分裂var的所有地方,唯一有问题的地方对我来说是内部短类型,例如,我更喜欢int I = 3;除以var I = 3;

对我来说,对var的反感说明了。net中双语的重要性。对于那些使用过VB . net的c#程序员来说,var的优势是显而易见的。标准的c#声明:

List<string> whatever = new List<string>();

在VB .NET中,相当于键入:

Dim whatever As List(Of String) = New List(Of String)

不过,在VB . net中没有人这样做。这样做是愚蠢的,因为从。net的第一个版本开始,你就可以这样做了…

Dim whatever As New List(Of String)

...它创建变量并在一个相当紧凑的行中初始化它。啊,但是如果你想要一个IList<string>,而不是一个List<string>?在VB .NET中,这意味着你必须这样做:

Dim whatever As IList(Of String) = New List(Of String)

就像你在c#中必须做的那样,显然不能使用var:

IList<string> whatever = new List<string>();

如果您需要不同的类型,它可以是。但优秀编程的基本原则之一是减少冗余,这正是var所做的。