c# - usage - vb net control




在C#中使用var關鍵字 (20)

Var根本不像變體。 這個變量仍然是強類型的,只是你沒有按鍵來獲得它。 您可以將其懸停在Visual Studio中查看該類型。 如果你正在閱讀印刷的代碼,那麼你可能需要稍微思考一下這個類型是什麼。 但是只有一行聲明它,並且有很多行使用它,所以給出一些體面的名字仍然是讓代碼更容易遵循的最佳方式。

是使用Intellisense懶惰? 它比整個名字更少打字。 還是有些工作較少但不值得批評的事情? 我認為有,var是其中之一。

在與同事討論在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;

這並不比equivilent foreach(var中的someList){// ...} equivilent更好。

這裡有一個關於類型安全性的真正問題 - 例如,如果我們要將查詢的結果放入一個接受IEnumerable <int>和IEnumerable <double>的重載方法中,調用方可能會無意中傳入錯誤的類型。

var 確實保持了強類型化,但問題是這種類型在定義時不會立即顯示是危險的,當重載意味著編譯器錯誤可能在您無意中將錯誤類型傳遞給方法時可能不會發出。


Var,在我看來,在C#中是件好事 。 任何這樣鍵入的變量仍然是強類型的,但是它從賦值的右側獲取它的類型。 由於類型信息在右側可用,因此在大多數情況下,沒有必要且過於冗長,因此也必須在左側輸入它。 我認為這會顯著提高可讀性而不會降低類型安全性。

在我看來,從可讀性的角度來看,使用變量和方法的良好命名約定比顯式類型信息更重要。 如果我需要類型信息,我總是可以將鼠標懸停在變量上(在VS中)並獲取它。 一般來說,讀者不需要明確的類型信息。 對於開發人員來說,在VS中你仍然可以獲得Intellisense,無論變量是如何聲明的。 儘管如此,仍然有些情況下,明確聲明類型是有意義的 - 也許你有一個返回List<T> ,但是你想在你的對像中將它作為IEnumerable<T>方法。 為了確保您使用的是接口,聲明接口類型的變量可以使其變得明確。 或者,也許你想聲明一個沒有初始值的變量 - 因為它立刻根據某種條件得到一個值。 在這種情況下,你需要這種類型。 如果類型信息有用或必要,請繼續使用它。 但我覺得,通常情況下這是沒有必要的,而且在大多數情況下,沒有它的代碼更容易閱讀。


@aku: One example is code reviews. Another example is refactoring scenarios.

Basically I don't want to go type-hunting with my mouse. It might not be available.


For the afficionados that think var saves time, it takes less keystrokes to type:

StringBuilder sb = new StringBuilder();

var sb = new StringBuilder();

Count em if you don't believe me...

19 versus 21

I'll explain if I have to, but just try it... (depending on the current state of your intellisense you may have to type a couple more for each one)

And it's true for every type you can think of!!

My personal feeling is that var should never be used except where the type is not known because it reduces recognition readabiltiy in code. It takes the brain longer to recognize the type than a full line. Old timers who understand machine code and bits know exactly what I am talking about. The brain processes in parallel and when you use var you force it to serialize its input. Why would anyone want to make their brain work harder? That's what computers are for.


I only use var when it's clear to see what type is used.

For example, I would use var in this case, because you can see immediately that x will be of the type "MyClass":

var x = new MyClass();

I would NOT use var in cases like this, because you have to drag the mouse over the code and look at the tooltip to see what type MyFunction returns:

var x = MyClass.MyFunction();

Especially, I never use var in cases where the right side is not even a method, but only a value:

var x = 5;

(because the compiler can't know if I want a byte, short, int or whatever)


I split var all over the places, the only questionable places for me are internal short types, eg I prefer int i = 3; over var i = 3;


It can certainly make things simpler, from code I wrote yesterday:

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }

This would have be extremely verbose without var .

Addendum: A little time spent with a language with real type inference (eg F#) will show just how good compilers are at getting the type of expressions right. It certainly has meant I tend to use var as much as I can, and using an explicit type now indicates that the variable is not of the initialising expression's type.


It's a matter of taste. All this fussing about the type of a variable disappears when you get used to dynamically typed languages. That is, if you ever start to like them (I'm not sure if everybody can, but I do).

C#'s var is pretty cool in that it looks like dynamic typing, but actually is static typing - the compiler enforces correct usage.

The type of your variable is not really that important (this has been said before). It should be relatively clear from the context (its interactions with other variables and methods) and its name - don't expect customerList to contain an int ...

I am still waiting to see what my boss thinks of this matter - I got a blanket "go ahead" to use any new constructs in 3.5, but what will we do about maintenance?



Stolen from the post on this issue at CodingHorror :

Unfortunately, you and everyone else pretty much got it wrong. While I agree with you that redundancy is not a good thing, the better way to solve this issue would have been to do something like the following:

MyObject m = new();

Or if you are passing parameters:

Person p = new("FirstName", "LastName);

Where in the creation of a new object, the compiler infers the type from the left-hand side, and not the right. This has other advantages over "var", in that it could be used in field declarations as well (there are also some other areas that it could be useful as well, but I won't get into it here).

In the end, it just wasn't intended to reduce redundancy. Don't get me wrong, "var" is VERY important in C# for anonymous types/projections, but the use here is just WAY off (and I've been saying this for a long, long time) as you obfuscate the type that is being used. Having to type it twice is too often, but declaring it zero times is too few.

Nicholas Paldino .NET/C# MVP on June 20, 2008 08:00 AM

I guess if your main concern is to have to type less -- then there isn't any argument that's going to sway you from using it.

If you are only going to ever be the person who looks at your code, then who cares? Otherwise, in a case like this:

var people = Managers.People

it's fine, but in a case like this:

var fc = Factory.Run();

it short circuits any immediate type deductions my brain could begin forming from the 'English' of the code.

Otherwise, just use your best judgment and programming 'courtesy' towards others who might have to work on your project.


Use it for anonymous types - that's what it's there for. Anything else is a use too far. Like many people who grew up on C, I'm used to looking at the left of the declaration for the type. I don't look at the right side unless I have to. Using var for any old declaration makes me do that all the time, which I personally find uncomfortable.

Those saying 'it doesn't matter, use what you're happy with' are not seeing the whole picture. Everyone will pick up other people's code at one point or another and have to deal with whatever decisions they made at the time they wrote it. It's bad enough having to deal with radically different naming conventions, or - the classic gripe - bracing styles, without adding the whole ' var or not' thing into the mix. The worst case will be where one programmer didn't use var and then along comes a maintainer who loves it, and extends the code using it. So now you have an unholy mess.

Standards are a good thing precisely because they mean you're that much more likely to be able to pick up random code and be able to grok it quickly. The more things that are different, the harder that gets. And moving to the 'var everywhere' style makes a big difference.

I don't mind dynamic typing, and I don't mind implict typing - in languages that are designed for them. I quite like Python. But C# was designed as a statically explicitly-typed language and that's how it should stay. Breaking the rules for anonymous types was bad enough; letting people take that still further and break the idioms of the language even more is something I'm not happy with. Now that the genie is out of the bottle, it'll never go back in. C# will become balkanised into camps. 不好。


Using var instead of explicit type makes refactorings much easier (therefore I must contradict the previous posters who meant it made no difference or it was purely "syntactic sugar").

You can change the return type of your methods without changing every file where this method is called. Imagine

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

which is used like

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

If you wanted to refactor SomeMethod() to return an IEnumerable<MySecondClass> , you would have to change the variable declaration (also inside the foreach ) in every place you used the method.

If you write

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

instead, you don't have to change it.


在某些情況下,我仍然認為var可以使代碼更具可讀性。 如果我有一個帶有Orders屬性的Customer類,並且我想將它分配給一個變量,我只需要這樣做:

var orders = cust.Orders;

我不關心,如果Customer.Orders是IEnumerable<Order>ObservableCollection<Order>BindingList<Order> - 我想要的是保持該列表在內存中迭代它或得到它的計數或稍後的東西。

將上述聲明與以下對比:

ObservableCollection<Order> orders = cust.Orders;

對我而言,類型名稱只是噪音。 如果我回去並決定改變Customer.Orders的類型(例如從ObservableCollection<Order>IList<Order> ),那麼我需要更改該聲明 - 我不需要做的事情如果我首先使用了var。


如果有人使用var關鍵字是因為他們不想“弄清楚類型”,那肯定是錯誤的原因。 var關鍵字不會創建具有動態類型的變量,編譯器仍然需要知道該類型。 由於變量總是具有特定類型,因此如果可能的話,該類型在代碼中也應該是明顯的。

例如,使用var關鍵字的好理由是:

  • 需要的地方,即為匿名類型聲明參考。
  • 它使代碼更具可讀性,即去除重複聲明。

寫出數據類型通常會使代碼更容易遵循。 它顯示了您正在使用的數據類型,因此您不必通過首先確定代碼的功能來確定數據類型。


我廣泛使用var 。 有人批評這會降低代碼的可讀性,但沒有理由支持這一說法。

誠然,這可能意味著我們不清楚我們正在處理什麼類型。 所以呢? 這實際上是一個分離設計的重點。 在處理接口時,你強調對變量的類型感興趣。 var更進一步,這是真的,但我認為從可讀性的角度來看,論點仍然是一樣的:程序員實際上不應該對變量的類型感興趣,而應該關注變量的作用 。 這就是為什麼微軟也稱為類型推斷“鴨子打字”。

那麼,當我使用var聲明它時,變量會做什麼? 很簡單,它可以做任何IntelliSense告訴我它做的事情。 任何關於C#忽略IDE的推理都不符合現實。 實際上,每個C#代碼都在支持智能感知的IDE中編程。

如果我正在使用var聲明的變量並且弄不清變量是什麼,那麼我的代碼就會出現一些根本性錯誤。 var不是原因,它只是使症狀可見。 不要責怪使者。

現在,C#團隊發布了一個編碼指南,指出該var 只能用於捕獲創建匿名類型的LINQ語句的結果(因為這裡我們沒有真正的var替代)。 那麼,擰緊。 只要C#團隊沒有給我這個指導方針一個合理的論點,我就會忽略它,因為在我的專業和個人意見中,這純粹是胡扯。 (對不起,我沒有鏈接到有關指南。)

實際上,為什麼你不應該使用var有一些(表面上) 很好的解釋 ,但我仍然認為它們在很大程度上是錯誤的。 以“searchabililty”為例:作者聲稱var很難搜索使用MyType地方。 對。 接口也是如此。 其實,為什麼我想知道課堂在哪裡? 我可能更感興趣的是它在哪裡實例化,這仍然是可搜索的,因為它的構造函數必須被調用(即使這是間接完成的,類型名稱必須在某處提及)。


我看不出有什麼大不了的。

var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!

你仍然對“某事”有完全的智能感知,對於任何含糊不清的情況,你有單元測試,對嗎? ( 你做? )

它不是varchar,它不暗淡,而且它不是動態或弱類型。 它正在阻止maddnes這樣:

List<somethinglongtypename> v = new List<somethinglongtypename>();

並將這個總體思路減少到:

var v = new List<somethinglongtypename>();

不錯,不如:

v = List<somethinglongtypename>();

但那就是Boo目的。


我認為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程序。 我的名字是馬特,我(ab)使用var。


最需要的時間是匿名類型(需要100%); 但它也避免了瑣碎情況的重複,並且IMO使線條更清晰。 對於簡單的初始化,我不需要兩次查看類型。

例如:

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和不使用時。

另一個值得關注的情況是,在接下來的調用中,您無法僅僅通過查看CallMe返回的代碼來判斷:

var variable = CallMe();

這是我對var的主要抱怨。

當我在方法中聲明匿名委託時,我使用var,不知何故var比使用Func更清晰。 考慮這個代碼:

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

編輯 :更新基於朱利安輸入的最後一個代碼示例


這些都不是絕對正確的。 var對可讀性有正面和負面的影響。 在我看來,當以下任一情況屬實時,應該使用var

  1. 該類型是匿名的(好吧,您在這裡沒有任何選擇,因為在這種情況下它必須是var)
  2. 類型很明顯基於賦值表達式(即var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating()

var沒有性能影響,因為它是句法糖; 編譯器推斷該類型,並在編譯為IL時將其定義; 實際上沒有什麼動態的。





var