在与同事讨论了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,在我看来,在c#中是一个很好的东西。任何这样类型的变量仍然是强类型的,但是它从赋值函数的右边得到它的类型。因为类型信息在右侧可用,在大多数情况下,也必须在左侧输入它是不必要的和过于冗长的。我认为这在不降低类型安全性的情况下显著提高了可读性。

From my perspective, using good naming conventions for variables and methods is more important from a readability perspective than explicit type information. If I need the type information, I can always hover over the variable (in VS) and get it. Generally, though, explicit type information shouldn't be necessary to the reader. For the developer, in VS you still get Intellisense, regardless of how the variable is declared. Having said all of that, there may still be cases where it does make sense to explicitly declare the type -- perhaps you have a method that returns a List<T>, but you want to treat it as an IEnumerable<T> in your method. To ensure that you are using the interface, declaring the variable of the interface type can make this explicit. Or, perhaps, you want to declare a variable without an initial value -- because it immediately gets a value based on some condition. In that case you need the type. If the type information is useful or necessary, go ahead and use it. I feel, though, that typically it isn't necessary and the code is easier to read without it in most cases.

其他回答

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

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

我认为VAR的关键是只在适当的地方使用它,即在Linq中做一些方便的事情(可能在其他情况下)。

如果你有一个类型的东西,那么你应该使用它-不这样做是简单的懒惰(与创造性的懒惰相反,这通常是被鼓励的-优秀的程序员往往非常努力地工作,懒惰,可以被认为是最初的东西的来源)。

全面禁止就像滥用这种结构一样糟糕,但确实需要一个合理的编码标准。

另一件需要记住的事情是,它不是VB类型变量,因为它不能改变类型——它是一个强类型变量,它只是类型是推断出来的(这就是为什么有人会认为在foreach中使用它不是不合理的,但出于可读性和可维护性的原因,我不同意)。

我怀疑这个会一直持续下去(-:

梅菲

@Keith -

在你们的比较中 IEnumerable < int > IEnumerable<double>你不需要 担心——如果你传递了错误的类型 您的代码无论如何都无法编译。

这并不完全正确——如果一个方法同时重载到IEnumerable<int>和IEnumerable<double>,那么它可能会无声地将意外推断的类型(由于程序中的其他一些更改)传递给错误的重载,从而导致不正确的行为。

我想问题是这种情况出现的可能性有多大!

我猜部分问题是var给给定的声明增加了多少混乱——如果不清楚某个东西是什么类型(尽管它是强类型的,编译器完全理解它是什么类型),有人可能会掩盖一个类型安全错误,或者至少需要更长的时间来理解一段代码。

没有,只是不需要写两次类型名。http://msdn.microsoft.com/en-us/library/bb383973.aspx

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