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

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

Employee emp = new Employee() any more obvious?

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

var emp = GetEmployee();

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

其他回答

我认为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。

将它用于匿名类型—这就是它存在的目的。其他的都是徒劳无功。像许多使用C长大的人一样,我习惯于查看类型声明的左侧。除非迫不得已,我是不会看右边的。在任何旧的声明中使用var都让我一直这样做,我个人觉得不舒服。

Those saying 'it doesn't matter, use what you're happy with' are not seeing the whole picture. Everyone will pick up other people's code at one point or another and have to deal with whatever decisions they made at the time they wrote it. It's bad enough having to deal with radically different naming conventions, or - the classic gripe - bracing styles, without adding the whole 'var or not' thing into the mix. The worst case will be where one programmer didn't use var and then along comes a maintainer who loves it, and extends the code using it. So now you have an unholy mess.

标准是一件好事,因为它们意味着你更有可能捡起随机代码,并能够快速地理解它。不同的东西越多,就越难。而转移到“无处不在的var”风格会有很大的不同。

I don't mind dynamic typing, and I don't mind implict typing - in languages that are designed for them. I quite like Python. But C# was designed as a statically explicitly-typed language and that's how it should stay. Breaking the rules for anonymous types was bad enough; letting people take that still further and break the idioms of the language even more is something I'm not happy with. Now that the genie is out of the bottle, it'll never go back in. C# will become balkanised into camps. Not good.

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

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

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

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

当你不想重复自己的时候,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;

令人惊讶的是,到目前为止还没有注意到这一点,但对foreach循环变量使用var是常识。

如果您指定了特定的类型,则可能会有编译器无声地将运行时强制转换插入程序的风险!

foreach (Derived d in listOfBase)
{

上面的代码将被编译。但是编译器会插入一个从Base到Derived的向下转换。因此,如果列表中的任何内容在运行时不是派生的,则存在无效的强制转换异常。类型安全受到损害。隐形演员太可怕了。

排除这种情况的唯一方法是使用var,因此编译器会根据列表的静态类型来确定循环变量的类型。