在与同事讨论了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确实保持强类型,但问题是,在定义中不立即显示类型是否危险,当重载意味着当你无意中将错误的类型传递给方法时,编译器可能不会发出错误,这种情况会被放大。
摘自CodingHorror关于这一问题的文章:
不幸的是,你和其他人都错了。虽然我同意你的观点,冗余不是一件好事,但解决这个问题的更好方法应该是这样做:
MyObject m = new();
或者如果你传递参数:
Person p = new("FirstName", "LastName ");
在创建新对象时,编译器从左边推断类型,而不是右边。这比“var”有其他优点,因为它也可以在字段声明中使用(还有其他一些领域,它也可能有用,但我不会在这里讨论)。
最后,这并不是为了减少冗余。不要误解我,“var”在c#中对于匿名类型/投影是非常重要的,但是这里的使用是非常错误的(我已经说了很长很长一段时间了),因为你混淆了正在使用的类型。输入两次太频繁了,但是声明0次就太少了。
2008年6月20日上午08:00,c#mvp
我想如果你主要关心的是必须少打字——那么没有任何争论会动摇你使用它。
如果你只是一个查看代码的人,那么谁在乎呢?否则,在这种情况下:
var people = Managers.People
没关系,但在这种情况下:
var fc = Factory.Run();
它使我的大脑从代码的“英文”开始形成的任何即时类型推断短路。
否则,就用你最好的判断和编程“礼貌”来对待那些可能不得不为你的项目工作的人。
我认为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。
在边缘情况下肯定会有分歧,但我可以告诉你我的个人指导方针。
当我决定使用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());
...
相反,你不需要改变它。