與同事討論了在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#會陷入困境。 很差。