与同事讨论了在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彷佛有点灰色,例如: app
var results = from r in dataContext.SomeTable select r; // Not *entirely clear* what results will be here.
很明显,它将产生一个实现IEnumerable的类型,但结果并不彻底相同,就像声明一个新对象的var同样。 this
当涉及对象的LINQ时,甚至更糟,例如: spa
var results = from item in someList where item != 3 select item;
这并不比等价的foreach(someList中的var item){// ...}等值好。 设计
这里确实有关于类型安全的问题-例如,若是咱们将查询的结果放入接受了IEnumerable <int>和IEnumerable <double>的重载方法中,则调用者可能会无心中传递错误的类型。 code
var
确实保持强类型,可是问题其实是类型在定义时不当即变得危险吗?当重载意味着当您无心将错误类型传递给方法时,可能不会发出编译器错误时,这种状况会放大。 orm
对我来讲,对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所作的。
没有,除了没必要两次键入类型名称。 http://msdn.microsoft.com/en-us/library/bb383973.aspx
您最可能须要的时间是匿名类型(要求100%); 但这也避免了琐碎的重复,国际海事组织使这一界限更加清晰。 我不须要两次查看类型便可进行简单的初始化。
例如:
Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();
(请不要在上面编辑hscroll-有点证实了这一点!!!)
vs:
var data = new Dictionary<string, List<SomeComplexType<int>>>();
可是,在某些状况下,这会产生误导,并可能致使错误。 若是原始变量和初始化类型不一样,请当心使用var
。 例如:
static void DoSomething(IFoo foo) {Console.WriteLine("working happily") } static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");} // this working code... IFoo oldCode = new Foo(); DoSomething(oldCode); // ...is **very** different to this code var newCode = new Foo(); DoSomething(newCode);
使用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()); ...
相反,您没必要更改它。
将其用于匿名类型-这就是它的用途。 其余任何用途都太远了。 像许多在C上长大的人同样,我习惯于在类型声明的左侧。 除非必须,不然我不会在右边看。 对任何旧声明使用var
会使我一直这样作,我我的感到不舒服。
那些说“不要紧,用本身满意的东西”的人并无看到所有。 每一个人都会在某一点或另外一点拾取别人的代码,而且必须处理他们在编写代码时所作的任何决定。 必须处理根本不一样的命名约定,或者-经典的抱怨-支撑样式,而又不添加整个“ var
or not”的东西,这已经够糟糕了。 最糟糕的状况是,一个程序员没有使用var
,而后出现了一个热爱它的维护者,并使用它来扩展代码。 因此如今你有一个邪恶的混乱。
标准刚好是一件好事,由于它们意味着您更有可能拾取随机代码并可以快速使用它。 不一样的事物越多,得到的难度就越大。 转变为“无处不在”的风格带来了很大的不一样。
我不介意动态打字,也不介意隐式打字-使用为他们设计的语言。 我很喜欢Python。 可是C#被设计为静态显式类型的语言,所以它应该保持不变。 打破匿名类型的规则已经很糟糕了。 我不满意让别人更进一步,打破语言的习语。 既然精灵已经从瓶子里拿出来了,就永远不会再回来了。C#会陷入困境。 很差。