在与同事讨论了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时,它会增加不一致性。

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

var variable = CallMe();

这是我对var的主要抱怨。

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

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

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

其他回答

在边缘情况下肯定会有分歧,但我可以告诉你我的个人指导方针。

当我决定使用var时,我看看这些标准:

变量的类型(对人来说)从上下文是很明显的 变量的确切类型(对人类来说)并不是特别相关。 [例如,你可以弄清楚算法在做什么,而不用关心你使用的是哪种容器] 类型名非常长,会影响代码的可读性(提示:通常是泛型)

相反,这些情况会促使我不使用var:

类型名称相对较短且易于阅读(提示:通常不是泛型) 从初始化式的名称来看,类型并不明显 确切的类型对于理解代码/算法非常重要 在类层次结构上,当一个人不能很容易地知道正在使用层次结构的哪个级别时

最后,我永远不会使用var的本机值类型或相应的可空<>类型(int,十进制,字符串,十进制?,……)。这里有一个隐含的假设,如果你使用var,一定有一个“原因”。

这些都是指导方针。你还应该考虑你同事的经验和技能,算法的复杂性,变量的寿命/范围,等等。

大多数时候,没有完美的正确答案。或者,这并不重要。

[编辑:删除重复的子弹]

使用var而不是显式类型使重构更容易(因此我必须反驳前面的帖子,他们的意思是它没有区别,或者它纯粹是“语法糖”)。

您可以更改方法的返回类型,而无需更改调用此方法的每个文件。想象一下

...
List<MyClass> SomeMethod() { ... }
...

就像这样

...
IList<MyClass> list = obj.SomeMethod();
foreach (MyClass c in list)
  System.Console.WriteLine(c.ToString());
...

如果您希望重构SomeMethod()以返回IEnumerable<MySecondClass>,则必须在使用该方法的每个地方更改变量声明(也在foreach中)。

如果你写

...
var list = obj.SomeMethod();
foreach (var element in list)
  System.Console.WriteLine(element.ToString());
...

相反,你不需要改变它。

在测试过程中,我发现自己的代码是这样的:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);

现在,有时,我想看看SomeOtherThing本身包含什么,SomeOtherThing不是CallMethod()返回的相同类型。因为我使用了var,我只是改变了这个:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();

:

var something = myObject.SomeProperty.SomeOtherThing;

如果没有var,我也必须不断改变左边声明的类型。我知道这是小事,但它非常方便。

我发现使用var关键字实际上使代码更具可读性,因为你只是习惯于跳过'var'关键字。当您真的不关心具体类型是什么时,您不需要一直向下滚动来弄清楚代码在做什么。如果我真的需要知道下面的“item”是什么类型,我只需将鼠标悬停在它上面,Visual Studio就会告诉我。换句话说,我更愿意读书

foreach( var item in list ) { DoWork( item ); }

一遍又一遍地

foreach( KeyValuePair<string, double> entry in list ) { DoWork( Item ); }

当我试图消化代码时。我认为这在某种程度上可以归结为个人喜好。在这一点上,我将依赖常识——在重要的方面(安全性、数据库使用、日志记录等)保留强制标准。

-工业。

好吧,这个问题会一直固执己见,但我会试着给出我的观点-尽管我认为我的观点是如此混乱,你可能不会从中得到什么。

首先——有匿名类型,为此你需要使用“var”关键字来分配一个匿名类型作为类的对象——这里没有太多的讨论,“var”是必要的。

然而,对于更简单的类型,如int型、长型、字符串型等等,我倾向于输入适当的类型。主要是因为它有点像“懒人的工具”,我在这里看不到太多的好处,很少的按键和它可能带来的困惑,这是不值得的。特别是浮点数的各种类型(浮点数、双精度数、十进制数)使我感到困惑,因为我对字面量中的后缀不坚定——我喜欢在源代码中看到类型。

话虽如此,如果类型更复杂和/或它显式地重复在赋值的右侧,我倾向于大量使用var。这可以是一个List<string>或etc,例如:

var list = new List<string>();

在这种情况下,我认为没有必要重复类型两次——特别是当您开始更改代码和类型更改时——泛型类型可能会变得越来越复杂,因此必须更改它们两次只是一种痛苦。当然,如果你希望针对IList<string>编码,那么你必须显式地命名类型。

简而言之,我做了以下事情:

当类型很短或不能脱离上下文读取时,显式地命名类型 在必要时使用var(废话) 当var(在我看来)不影响可读性时,使用它来偷懒