Użycie słowa kluczowego var w C #

406

Po dyskusji z kolegami na temat użycia słowa kluczowego „var” w C # 3 zastanawiałem się, jakie są opinie ludzi na temat właściwego zastosowania wnioskowania typu przez var?

Na przykład dość leniwie używałem var w wątpliwych okolicznościach, np .:

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.

Bardziej uzasadnione użycie var jest następujące:

var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.

Co ciekawe, LINQ wydaje się być trochę szarym obszarem, np .:

var results = from r in dataContext.SomeTable
              select r; // Not *entirely clear* what results will be here.

Jest oczywiste, jakie będą wyniki, ponieważ będzie to typ, który implementuje IEnumerable, jednak nie jest to całkowicie oczywiste w taki sam sposób, jak var deklarujący nowy obiekt.

Jest jeszcze gorzej, jeśli chodzi o LINQ do obiektów, np .:

var results = from item in someList
              where item != 3
              select item;

Nie jest to lepsze niż równoważnik foreach (var item in someList) {// ...} ekwiwalent.

Istnieje poważna obawa o bezpieczeństwo typu - na przykład, gdybyśmy umieścili wyniki tego zapytania w przeciążonej metodzie, która zaakceptowała IEnumerable <int> i IEnumerable <double>, osoba dzwoniąca mogłaby przypadkowo przekazać niewłaściwy typ.

var ma utrzymać silną wpisywanie ale pytanie jest naprawdę, czy jest to niebezpieczne dla typu, aby nie być od razu widoczne na definicji, coś, co jest powiększony przy przeciążeniach średnie błędy kompilatora nie może być wydane, gdy nieumyślnie przekazać niewłaściwy typ sposobu.

ljs
źródło
68
Używanie var jest w porządku, ale „Nie muszę rozróżniać typu” wydaje się być bardzo złym powodem do używania go ... powinieneś wiedzieć, jaki jest typ, var jest tylko skrótem, aby uniknąć pisania
Thomas Levesque
53
var i = 0;== niepowodzenie! var c = new CrazyFrigginLongClassName();== wygraj!
dotjoe
6
„Var przypomina mi również typ wariantu VB / VBA. Miał również swoje miejsce. Pamiętam (sprzed wielu lat), że jego użycie było mniej niż pożądane i było raczej głodne zasobów”. <- pokazuje, że jest to przynęta, ponieważ typ „var” języka C # nie ma nic wspólnego z typem wariantu VB / VBA.
user7116
20
var readabilityBeDamned = true;
spoulson
9
Problem ze wszystkimi podanymi tutaj przykładami polega na tym, że patrzymy na JEDEN wiersz kodu. Kiedy widzę jeden po drugim wiersz po wierszu deklaracji „var”, wymyka się spod kontroli. Czytelność jest subiektywna, ale uważam, że var jest nadużywany o wiele bardziej niż jest stosowany z szacunkiem.
jro,

Odpowiedzi:

293

Nadal uważam, varże w niektórych przypadkach kod może być bardziej czytelny. Jeśli mam klasę Customer z właściwością Orders i chcę przypisać ją do zmiennej, po prostu zrobię to:

var orders = cust.Orders;

Nie obchodzi mnie, czy Customer.Orders jest IEnumerable<Order>, ObservableCollection<Order>czyBindingList<Order> - wszystko, czego chcę, to zachować tę listę w pamięci, aby iterować nad nią lub uzyskać jej liczbę lub coś później.

Porównaj powyższą deklarację z:

ObservableCollection<Order> orders = cust.Orders;

Dla mnie nazwa typu to po prostu hałas. A jeśli wrócę i zdecyduję się zmienić typ klienta. Zamówienia w dół ścieżki (powiedzmy od ObservableCollection<Order>do IList<Order>) to muszę również zmienić tę deklarację - coś, czego nie musiałbym zrobić, gdybym użył var w pierwszym miejsce.

Matt Hamilton
źródło
48
Lubię czytać kod przed sobą. Skąd mam wiedzieć, co to jest „zamówienie” bez typu? Tak, mógłbym najechać myszką, aby się dowiedzieć, ale dlaczego miałbym to robić? :)
Jon Tackabury
77
Ale chodzi o to, że ogólnie nie ma to znaczenia. Dostarczony klient. Zamówienia to coś, co można wyliczyć (np. Przedpremierowo), to nie ma znaczenia, jaki to rodzaj. Dodatkowy kod przeszkadza w odczytaniu zamiaru.
Matt Hamilton
67
Ale jeśli potrzebujesz tylko tego cust.Orders jest „czymś, co możesz wyliczyć”, to czy nie deklarowanie go jako IEnumerable <Order> nie czyni tego wymogu wyraźnym i jasnym? Podanie go jako var oznacza, że ​​skutecznie tracisz ten wymóg.
GrahamS,
5
@jon i jak IEnumerbal rozkazy = cust.Zamówienia zamówień (zmienna kolejność w zamówieniach) mają znaczenie? jedyną rzeczą, którą IEnumerable mówi, jest to, że możesz umieścić to w foreach, ale już wiedziałeś o tym z poniższej linii
Rune FS
18
„jedyną rzeczą, którą IEnumerable mówi, jest to, że możesz umieścić to w foreach” - wyraża także zamiar, aby jedyną rzeczą, którą możesz zrobić, jest wyliczenie. Korzystanie z var zapewnia dostęp i inteligencję publicznym członkom konkretnego typu kolekcji.
Joe
167

używam var intensywnie. Pojawiła się krytyka, że ​​zmniejsza to czytelność kodu, ale nie ma argumentu na poparcie tego twierdzenia.

Wprawdzie może to oznaczać, że nie jest jasne, z jakim typem mamy do czynienia. Więc co? To jest właściwie cel oddzielonego projektu. Podczas pracy z interfejsami zdecydowanie nie interesuje Cię typ zmiennej. varidzie to o wiele dalej, prawda, ale myślę, że argument pozostaje taki sam z punktu widzenia czytelności: programista nie powinien być zainteresowany typem zmiennej, ale raczej tym, co robi zmienna . Właśnie dlatego Microsoft nazywa również wnioskowanie typu „pisanie kaczką”.

Co więc robi zmienna, kiedy ją deklaruję var? Łatwo, robi to, co mówi mi IntelliSense. Wszelkie rozumowania dotyczące C #, które ignorują IDE, nie są realne. W praktyce każdy kod C # jest programowany w środowisku IDE obsługującym IntelliSense.

Jeśli używam varzadeklarowanej zmiennej i mylę się, po co jest zmienna, w moim kodzie jest coś zasadniczo nie tak. varnie jest przyczyną, powoduje jedynie, że objawy są widoczne. Nie obwiniaj posłańca.

Teraz zespół C # wydał wytyczne dotyczące kodowania, które varpowinny być używane tylko do przechwytywania wyniku instrukcji LINQ, która tworzy typ anonimowy (ponieważ tutaj nie mamy prawdziwej alternatywy var). Cóż, pieprzyć to. Dopóki zespół C # nie da mi solidnego argumentu za tą wytyczną, będę ją ignorować, ponieważ moim profesjonalnym i osobistym zdaniem jest to czysty baloney. (Przepraszam; nie mam linku do omawianych wytycznych.)

W rzeczywistości istnieją pewne (powierzchownie) dobre wyjaśnienia, dlaczego nie powinieneś używać, varale nadal uważam, że są w dużej mierze błędne. Weźmy przykład „wyszukiwalności”: autor twierdzi, że varutrudnia to wyszukiwanie miejsc, w których MyTypejest używany. Dobrze. Podobnie jak interfejsy. Właściwie dlaczego miałbym chcieć wiedzieć, gdzie jest używana klasa? Mógłbym być bardziej zainteresowany tym, gdzie jest on tworzony, a to nadal będzie możliwe do przeszukiwania, ponieważ gdzieś trzeba wywołać jego konstruktor (nawet jeśli jest to zrobione pośrednio, należy podać gdzieś nazwę typu).

Konrad Rudolph
źródło
14
W żadnym przyzwoitym IDE, nie używasz wyszukiwania tekstowego, aby uzyskać użycie klasy, dostajesz IDE, aby to zrobić na podstawie jego drzewa analizy lub w inny sposób identyfikuje typy obiektów. Ponieważ mówimy o pisaniu statycznym, znajdzie to wszystko oprócz typów anonimowych.
Dustman,
6
Nienawidzę dziedziczyć 100 000 linii źródłowych bez dokumentacji i swobodnego korzystania z var. Zwłaszcza, jeśli łączysz var z mniej niż pomocnymi nazwami zmiennych. Widziałem, że jest to pomocne podczas ilustrowania punktu (lub radzenia sobie z typami anonimowymi), ale w kodzie produkcyjnym?
Shea,
7
Arnshea: już wskazałeś prawdziwy problem: bezużyteczne nazwy zmiennych i brakującą dokumentację . Naprawdę nie rozumiem, co varprzyczynia się do zamieszania. Z pewnością mogą zdarzyć się przypadki, w których ważne jest podkreślenie rodzaju / wielkości zmiennej (np. Operacje bitowe niskiego poziomu). W porządku: nikt nigdy nie twierdził, że varnależy go używać wyłącznie. Zasada jest prosta: jeśli naprawdę powoduje zamieszanie, nie używaj jej.
Konrad Rudolph
17
Każdy przykład przeciwny do var, który widziałem, zakłada, że ​​programista będzie używał bez znaczenia nazw zmiennych. Być może dlatego var jest lepszy niż jawne określenie typu: Zmusza programistę do wymyślenia dobrych nazw zmiennych.
Ryan Lundy,
16
Microsoft nazywa również wnioskowanie typu „pisanie kaczki”. - czy oni naprawdę? Byłbym zszokowany ...
Anton Tykhyy,
118

Var, moim zdaniem, w C # jest rzeczą dobrą tm . Każda tak wpisana zmienna jest nadal silnie wpisana, ale pobiera swój typ z prawej strony przypisania, w którym jest zdefiniowana. Ponieważ informacje o typie są dostępne po prawej stronie, w większości przypadków niepotrzebne i nadmiernie gadatliwe jest również wprowadzanie ich po lewej stronie. Myślę, że to znacznie zwiększa czytelność bez zmniejszania bezpieczeństwa typu.

Z mojego punktu widzenia stosowanie dobrych konwencji nazewnictwa dla zmiennych i metod jest ważniejsze z punktu widzenia czytelności niż wyraźne informacje o typie. Jeśli potrzebuję informacji o typie, zawsze mogę najechać wskaźnikiem na zmienną (w VS) i uzyskać ją. Zasadniczo jednak czytelne informacje o typie nie powinny być konieczne. Dla programisty w VS nadal otrzymujesz Intellisense, niezależnie od tego, jak deklarowana jest zmienna. Powiedziawszy to wszystko, mogą nadal występować przypadki, w których sensowne jest jawne zadeklarowanie typu - być może masz metodę, która zwracaList<T> , ale chcesz traktować ją jakoIEnumerable<T>w twojej metodzie. Aby upewnić się, że korzystasz z interfejsu, zadeklarowanie zmiennej typu interfejsu może to wyraźnie wyjaśnić. A może chcesz zadeklarować zmienną bez wartości początkowej - ponieważ natychmiast otrzymuje wartość na podstawie pewnego warunku. W takim przypadku potrzebujesz tego typu. Jeśli informacje o typie są przydatne lub konieczne, skorzystaj z nich. Wydaje mi się jednak, że zazwyczaj nie jest to konieczne, a kod jest łatwiejszy do odczytania bez niego w większości przypadków.

tvanfosson
źródło
3
Zgadzam się ogólnie. Moim zdaniem kluczową kwestią jest upewnienie się, że zamiar jest jasny. Jeśli nie jest to jasne dla większości programistów w zespole, jest szkodliwe, nie jest pomocne. To powiedziawszy, osobiście jestem OGROMNYM fanem tego, ale musiałem się trochę opanować, gdy inni deweloperzy z mojego zespołu mieli problemy z określeniem moich zamiarów. Domyśl.
Steve Brouillard,
3
Eh, łatwiej mi czytać, gdy czcionka jest po lewej stronie. Używając ReSharper, nie muszę i tak wpisywać tekstu po prawej stronie, więc mi to nie przeszkadza.
BlueRaja - Danny Pflughoeft
1
@BlueRaja - Uważam, że używanie dobrych nazw zmiennych zwykle eliminuje potrzebę zawracania sobie głowy faktycznym typem, aby zrozumieć. Intellisense jest nadal dostępny dla zmiennych zdefiniowanych „var”, więc nie muszę znać typu, aby wybrać metodę / właściwość przy kodowaniu.
tvanfosson
2
Nie chodzi o to, kiedy kodujesz, ale o to, kiedy musisz przeczytać kod.
BlueRaja - Danny Pflughoeft
1
Muszę więc być po prostu gruba, potrzebuję dobrej metody i nazw zmiennych oraz zrozumienia obsługiwanych typów, aby móc poprawnie zrozumieć kod, który czytam. Myślę, że masz rację, choć jest to objaw większych problemów. Jeden z zaufania. Aby mieć pewność, że kod działa tak, jak się wydaje, należy upewnić się, że używane są typy.
AnthonyWJones
91

Żadne z nich nie jest absolutnie prawdziwe; varmoże mieć zarówno pozytywny, jak i negatywny wpływ na czytelność. Moim zdaniem varpowinien być stosowany, gdy spełniony jest jeden z poniższych warunków:

  1. Typ jest anonimowy (cóż, tutaj nie masz wyboru, ponieważ w tym przypadku musi być zmienny)
  2. Typ jest oczywisty na podstawie przypisanego wyrażenia (tj. var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating())

varnie ma wpływu na wydajność, ponieważ jest cukrem syntaktycznym; kompilator określa typ i definiuje go po skompilowaniu do IL; nic faktycznie dynamiczny o nim.

Adam Robinson
źródło
1
zgadzam się co do obu, chociaż mam długie ograniczenia w stosunku do drugiego przypadku, jeśli typ jest taki długi, to zwykle jest to typ ogólny z wieloma zagnieżdżonymi ogólnymi argumentami, w tym przypadku silnie typowany „ShortType równoważny TypeWithAReallyLongNameTheresNoSenseRepeating” ma większy sens
Ion Todirel
12
Nie chcę rozpętać wojny religijnej, ale osobiście nie zgadzam się z Jonem. Wolałbym bardzo długą, ale bardzo dokładną nazwę typu (ala wujek Bob Martin) niż skróconą i być może dwuznaczną krótszą nazwę typu. Dodam zastrzeżenie, że NIE zgadzam się ze sztucznym zawyżaniem długości nazwy. Jeśli 5 znaków tworzy zwięzłą nazwę, która wyraźnie pokazuje zamiar, użyj 5, a nie 25.
Steve Brouillard
2
@ Steve: Muszę się z tobą zgodzić; tworzenie „krótkiego typu” (co, jak zakładam, rozumiesz jako dziedziczenie od określonego rodzaju ogólnego wyłącznie w celu skrócenia nazwy), nie jest dobrą praktyką; będzie wymagać od Ciebie skopiowania i przekazania dowolnego konstruktora z typu ogólnego, a także zapobiegnie przekazaniu do funkcji innego typu, który dziedziczy z typu ogólnego do funkcji. Używasz dziedziczenia jak typedefwtedy, gdy nie jest.
Adam Robinson
7
Używać, vargdy typ jest oczywisty? Może, ale prawdziwy zysk ma miejsce, gdy typ nie ma znaczenia. Jeśli robisz takie rzeczy var customers = whatever; var query = from c in customers select stuff, nie ma znaczenia, jaki dokładnie jest rodzaj „klientów”. To oczywiste, jak możesz z niego korzystać i to wystarczy. A jeśli rzeczywisty typ jest uciążliwy, warto go stłumić.
Joren
2
@Kristoffer: Rozumiem, że chcę wyeliminować bałagan tagów, ale zawinięcie ich w klasę nie jest (IMO) akceptowalną alternatywą, ponieważ wtedy odciąłeś możliwość jakiejkolwiek innej (legalnej) klasy potomnej tego typu ogólnego od bycia poprawny parametr. Wolałbym zastosować using ShortType = LongGenericType<A,B,C>dyrektywę na górze pliku, ponieważ daje to taką samą czytelność, nie wymaga ponownego tworzenia konstruktorów i nie eliminuje klas potomnych z kandydatów.
Adam Robinson
68

Eric Lippert, starszy inżynier oprogramowania w zespole C #:

Dlaczego varwprowadzono słowo kluczowe?

Istnieją dwa powody, jeden istniejący dzisiaj, jeden, który pojawi się w wersji 3.0.

Pierwszym powodem jest to, że ten kod jest niesamowicie brzydki z powodu całej nadmiarowości:

Dictionary<string, List<int>> mylists = new Dictionary<string, List<int>>();

I to jest prosty przykład - napisałem gorzej. Za każdym razem, gdy będziesz zmuszony wpisać dokładnie to samo dwa razy, możemy usunąć nadmiarowość. O wiele ładniej pisać

var mylists = new Dictionary<string,List<int>>();

i pozwól kompilatorowi dowiedzieć się, jaki typ jest oparty na przypisaniu.

Po drugie, C # 3.0 wprowadza anonimowe typy. Ponieważ typy anonimowe z definicji nie mają nazw, musisz być w stanie wywnioskować typ zmiennej z wyrażenia inicjującego, jeśli jej typ jest anonimowy.

Podkreśl moje. Cały artykuł, C # 3.0 jest wciąż statycznie wpisany, szczerze! , a kolejne serie są całkiem dobre.

Po to varjest. Inne zastosowania prawdopodobnie nie będą działać tak dobrze. Każde porównanie z JScript, VBScript lub pisaniem dynamicznym jest całkowitą koją. Uwaga: varjest wymagana , aby niektóre inne funkcje działały w .NET.

Dustman
źródło
Uważam argument Lipperta za dziwny. Nikt nie wpisuje nazwy drugiej klasy, pozwala Intellisense napisać ją dla nich, ale potem odwraca się i twierdzi, że var jest lepszy, ponieważ kompilator / Intellisense to rozwiązuje. Nie możesz mieć tego na dwa sposoby!
Dave
5
Zespół C # nie kontroluje inteligencji, kontroluje kompilator. W każdym razie nie jest to główny problem. Nie sądzę, żeby var zrobiłby 100 punktów na oszczędzaniu na pisaniu samemu.
Dustman,
@Dustman: var w ogóle nie zapisuje pisania. To sprawia, że ​​piszesz więcej!
Piotr Perak,
53

Myślę, że użycie var powinno być połączone z mądrze wybranymi nazwami zmiennych.

Nie mam problemu z użyciem var w instrukcji foreach, pod warunkiem, że nie jest tak:

foreach (var c in list) { ... }

Gdyby było mniej więcej tak:

foreach (var customer in list) { ... }

... wtedy ktoś czytający kod znacznie chętniej zrozumie, czym jest „lista”. Jeśli masz kontrolę nad nazwą samej zmiennej listy, to nawet lepiej.

To samo może dotyczyć innych sytuacji. Jest to dość bezużyteczne:

var x = SaveFoo(foo);

... ale to ma sens:

var saveSucceeded = SaveFoo(foo);

Chyba każdy na swój. Przekonałem się, że robię to, co jest po prostu szalone:

var f = (float)3;

Potrzebuję 12-etapowego programu var. Nazywam się Matt i ja (ab) używam var.

Matt Matt Hamilton
źródło
6
Cóż, jedyną rzeczą nie tak z „var f = (float) 3;” jest to, że powinna to być „var f = 3f” lub „var f = 3.0 (powoduje pojedynczą precyzję do bani)”.
MichaelGG
3
Heh yeah 3f lub 3.0 to najlepsza droga! My, maniacy, musimy trzymać się razem!
Matt Hamilton
27
Prawdziwym problemem w tym pierwszym przykładzie jest „lista”, a nie „c”. „lista” czego ? „lista” powinna zostać zmieniona na „klienci”, „klienciWhoOweMoney”, „obecni klienci” lub na coś o wiele bardziej opisowego. A kiedy już to zrobisz, „c” może pozostać takie, jakie jest, ponieważ już wiesz, co będzie zawierać.
Ryan Lundy,
4
Cześć Matt! Nazywam się Kenny i jestem varaddict.
kenny
var MattHamil = "Luke Skywalker"; // zdejmowałem z tego tonę
Binoj Antony
40

Przyjęliśmy etos „Kod dla ludzi, a nie maszyn”, oparty na założeniu, że spędzasz wiele razy więcej w trybie konserwacji niż na nowym rozwoju.

Dla mnie wyklucza to argument, że kompilator „wie”, jakiego typu jest zmienna - na pewno nie możesz napisać niepoprawnego kodu za pierwszym razem, ponieważ kompilator zatrzymuje kompilowanie kodu, ale gdy następny programista czyta kod w ciągu 6 miesięcy muszą być w stanie wywnioskować, co robi zmienna poprawnie lub niepoprawnie, i szybko zidentyfikować przyczynę problemów.

A zatem,

var something = SomeMethod();

jest zabronione przez nasze standardy kodowania, ale nasz zespół zachęca do następujących działań, ponieważ zwiększa to czytelność:

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
   DoWork( item ); 
}
Dexter
źródło
4
Przekonałem się, że („Kod dla ludzi, nie maszyn”) jest doskonałą wskazówką - przestrzeganie go może skutkować lepszym kodem i pomaga uniknąć przedwczesnej optymalizacji.
Thanatos
3
Nie otrzymuję listy var = new KeyValuePair <string, double>? Dla mnie lista może mieć więcej niż coś.
TTT
„Kod dla ludzi, a nie maszyn” - amen.
user1068352,
39

Nie jest źle, to bardziej stylistyczna rzecz, która wydaje się być subiektywna. Może dodawać niespójności, kiedy używasz var, a kiedy nie.

Kolejny niepokojący przypadek: w poniższym wywołaniu nie można po prostu spojrzeć na kod zwracany przez typ CallMe:

var variable = CallMe();

To moja główna skarga przeciwko var.

Używam var, kiedy deklaruję anonimowych delegatów metodami, jakoś var wygląda na czystsze niż gdybym używał Func. Rozważ ten kod:

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

EDYCJA : Zaktualizowałem ostatnią próbkę kodu na podstawie danych wejściowych Juliana

Jon Todirel
źródło
3
Ale czy naprawdę musisz znać typ tam, na tej linii? Wiesz, że CallMe coś zwraca; czy nie wystarczy wiedzieć, że variabletworzona jest zmienna lokalna o nazwie ? O ile nie poszerzysz swojego przykładu, nie jest to zbyt solidna skarga, IMO.
Randolpho
2
Nie chodzi o to, aby nie być gadatliwym, chodzi o to, aby kompilator nie zrobił dla ciebie cukru składniowego. Rozważ to: var getter ..., teraz ten Func <obiekt> getter ..., z tym drugim, że wiesz, że nie musisz podawać żadnych parametrów i co zwraca. Wiesz od samego początku „co robić” i możesz szybciej podejmować decyzje, projektując coś lub refaktoryzując. Posiadanie wszystkich dostępnych informacji jest ważniejsze niż kilka innych postaci. Można to docenić tylko przy pracy z dużą ilością kodu.
Ion Todirel
2
Ponieważ i tak wszyscy rozmawiamy o studiu wizualnym, o co chodzi z najechaniem myszką na zmienną przez sekundę i zobaczeniem, jaki to jest typ? W każdym razie znacznie lepiej niż bieganie do deklaracji.
Rubys
3
Ogólne nazwy zmiennych i funkcji ( variable, CallMe) stanowią złe przykłady. Gdyby jednak CallMe()była funkcja w jakiejś „aplikacji telefonicznej”, var call = CallMe(); .... call.HangUp();miałaby znacznie większy sens.
Danko Durbić
3
@Randolpho: „o co chodzi z najechaniem kursorem myszy na zmienną przez sekundę i zobaczeniem, jaki to typ?” Dodaje czas na koszty konserwacji ... plus jedna sekunda to tylko czas najechania myszą, a nie liczenie przełączania kontekstu z klawiatury na mysz. Nie wiem o tobie, ale pracuję z terminem. Za każdym razem, gdy muszę najechać kursorem na zmienną, aby dowiedzieć się, jaki to jest typ, jest czas, który mógłbym lepiej poświęcić na rozwiązywanie problemu.
Władca
36

Var wcale nie jest jak wariant. Zmienna jest nadal silnie wpisana, po prostu nie naciskasz klawiszy, aby uzyskać ją w ten sposób. Możesz najechać na niego kursorem w Visual Studio, aby zobaczyć typ. Jeśli czytasz drukowany kod, być może będziesz musiał pomyśleć, aby dowiedzieć się, jaki jest typ. Ale jest tylko jedna linia, która go deklaruje, i wiele linii, które go używają, więc nadawanie rzeczom przyzwoitych nazw jest nadal najlepszym sposobem na ułatwienie śledzenia kodu.

Czy używanie Intellisense jest leniwe? To mniej pisania niż całe imię. Czy są rzeczy, które są mniej pracy, ale nie zasługują na krytykę? Myślę, że są, a var jest jednym z nich.

Kate Gregory
źródło
6
+1, tylko osoba do zapamiętania, varktóra nie ma z tym nic wspólnego Variant.
user7116
27

Najbardziej prawdopodobny czas, jaki będziesz tego potrzebować, dotyczy typów anonimowych (gdy jest to wymagane w 100%); ale pozwala również uniknąć powtórzeń w trywialnych przypadkach, a IMO czyni linię wyraźniejszą. Nie muszę widzieć tego typu dwukrotnie w celu prostej inicjalizacji.

Na przykład:

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();

(proszę nie edytować hscroll powyżej - to trochę potwierdza sens !!!)

vs:

var data = new Dictionary<string, List<SomeComplexType<int>>>();

Są jednak sytuacje, w których jest to mylące i może potencjalnie powodować błędy. Zachowaj ostrożność, varjeśli oryginalna zmienna i typ inicjowany nie były identyczne. Na przykład:

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);
Marc Gravell
źródło
1
(dla informacji można uzyskać podobne problemy we wszystkich przypadkach, w których jest to domyślna konwersja typu)
Marc Gravell
1
Nie zgadzaj się z tą częścią, że nie chcesz widzieć go dwa razy w tej samej linii. Możliwe, że w przyszłości nie będziesz tworzył bezpośrednio zmiennej po zadeklarowaniu (na przykład w if poniżej definicji), ponieważ może nie być bezpośrednio jasne, jaki jest typ. Większość programistów używa tego typu bezpośrednio na początku wiersza, szczególnie w złożonym kodzie, którego nie chcesz utrudniać czytania kodu.
Gertjan
@TheVillageIdiot - Cofnąłem twoją edycję, ponieważ przy tej okazji hscroll jest powiązany z tym punktem ;-p
Marc Gravell
2
@Gertjan - mój mózg jest ograniczony; jeśli jest złożony, nie chcę go widzieć dwa razy i muszę zacząć porównywać (interfejs / beton / etc). Cieszę się, że raz to widzę i myślę „wpisany jako jeden z nich”.
Marc Gravell
17

Jeden szczególny przypadek, w którym var jest trudny: przeglądy kodu offline, zwłaszcza te wykonane na papierze.

Nie możesz w tym celu polegać na najechaniu myszką.

Jon Limjap
źródło
17
Dlaczego, do cholery, przeglądasz kod na papierze? Pomyśl o drzewach! ;)
Dustman
8
Możesz mieć ten sam problem bez używania var. Problemem nie jest var; problemem są złe nazwy zmiennych. Jeśli nazwy zmiennych są dobrze wybrane, użycie var nie ma znaczenia.
Ryan Lundy,
W moim zespole jest facet, który przegląda własny kod i szuka błędów, drukując swój kod. Jego ściany pokryte są kodem. Kiedyś wszedłem, a on miał całą dużą tablicę pokrytą jednym ze swoich ćwiczeń debugowania. Prawdopodobnie było to ~ 10000 LOC
Beep beep
Same nazwy zmiennych nie rozwiążą problemu, chyba że wrócisz do węgierskiej notacji, w której typ jest częścią nazwy.
Kevin Gale
17

Nie rozumiem o co chodzi ...

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

Nadal masz pełną inteligencję na „czymś”, aw każdym niejednoznacznym przypadku masz testy jednostkowe, prawda? ( czy ty? )

To nie jest varchar, nie jest słabe, a na pewno nie jest dynamiczne ani słabe pisanie. To powstrzymuje Maddnesa w ten sposób:

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

i redukując ten totalny bałagan do:

var v = new List<somethinglongtypename>();

Fajnie, nie tak ładnie jak:

v = List<somethinglongtypename>();

Ale do tego właśnie służy Boo .

Frep D-Oronge
źródło
rodzaj „czegoś” jest bardzo jasny dla kompilatora, wewnętrznie „var” jest ustawiany na zwracany typ „someMethod”, jest to jasne dla kompilatora, ale może nie być jasne dla programistów pracujących nad projektem. i Boo szybko na mnie rośnie.
stephenbayer
Nie, v = List<somethinglongtypename>();nie jest nawet milszy. Ważne jest rozróżnienie między wprowadzaniem nowej zmiennej a przypisywaniem do istniejącej zmiennej.
HighCommander4
Cóż, jeśli wcześniej przypisałeś do „v” w bieżącym zakresie, to jest to przypisanie do istniejącego. W przeciwnym razie jest to przypisanie do nowej zmiennej „v”. Łatwy.
Frep D-Oronge
17

Jeśli ktoś używa varsłowa kluczowego, ponieważ nie chce „ustalić typu”, jest to zdecydowanie zły powód. Słowo varkluczowe nie tworzy zmiennej o typie dynamicznym, kompilator nadal musi znać ten typ. Ponieważ zmienna zawsze ma określony typ, typ powinien być również widoczny w kodzie, jeśli to możliwe.

Dobrym powodem do użycia tego varsłowa kluczowego są na przykład:

  • Tam, gdzie jest to potrzebne, tj. Do zadeklarowania referencji dla anonimowego typu.
  • Gdzie sprawia, że ​​kod jest bardziej czytelny, tzn. Usuwa powtarzające się deklaracje.

Zapisanie typu danych często ułatwia śledzenie kodu. Pokazuje typy danych, których używasz, abyś nie musiał rozgryzać typu danych, najpierw zastanawiając się, co robi kod.

Guffa
źródło
11

Biorąc pod uwagę, jak potężna jest teraz Intellisense, nie jestem pewien, czy var jest trudniejszy do odczytania niż posiadanie zmiennych składowych w klasie lub zmiennych lokalnych w metodzie zdefiniowanej poza widocznym obszarem ekranu.

Jeśli masz wiersz kodu, taki jak

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Jest o wiele łatwiejszy lub trudniejszy do odczytania niż:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();
Colin Desmond
źródło
Właściwie nie zastanawiałem się nad tym, jak wynika z drugiego pytania, które jest dość mocną stroną, aby użyć go jeszcze raz.
Finglas
To był w zasadzie jedyny powód, dla którego go zaimplementowali (oprócz możliwości deklarowania typów anonimowych, ale mogliby uczynić „var” specjalnym słowem kluczowym, które było tylko dla typów anonimowych)
mqp
10

Myślę, że kluczową rzeczą w VAR jest używanie go tylko tam, gdzie jest to właściwe, tj. Podczas robienia rzeczy w Linq, które to ułatwia (i prawdopodobnie w innych przypadkach).

Jeśli masz typ czegoś w czym należy go używać - nie do tego jest prosty lenistwo (w przeciwieństwie do twórczego lenistwa, które jest ogólnie zachęcać - dobra programiści często pracują bardzo ciężko, aby być leniwy i mogą być uznane źródło rzeczy w pierwszej kolejności).

Całkowity zakaz jest tak samo zły jak nadużywanie konstruktu, ale musi istnieć rozsądny standard kodowania.

Inną rzeczą do zapamiętania jest to, że nie jest to zmienna typu VB, ponieważ nie może zmieniać typów - jest to zmienna o silnym typie, po prostu wnioskuje o typie (dlatego są ludzie, którzy twierdzą, że nie jest nierozsądne użyj go, powiedzmy, w foreach, ale nie zgodzę się ze względu zarówno na czytelność, jak i konserwację).

Podejrzewam, że ten będzie działać i działać (-:

Murph

Murph
źródło
10

Jasne, intjest łatwe, ale gdy typem zmiennej jest IEnumerable<MyStupidLongNamedGenericClass<int, string>>, var znacznie ułatwia.

Blorgbeard wyszedł
źródło
2
+1 za to. intversus varjest czymś, o co można się sprzeczać, ale wiele zagnieżdżonych rodzajów ogólnych varstanowi dar niebios. W tym miejscu wielokrotne używanie nazwy typu niszczy czytelność kodu.
Chris Farmer
Jest to absolutnie niewłaściwy powód jego używania. Jeśli twój kod używa zagnieżdżonego typu ogólnego, powinieneś uzyskać dla niego określoną nazwaną klasę. Na przykład: class IntStringEnumerator : IEnumerable<MyStupidLongNamedGenericClass<int, string>>a następnie użyj nowej nazwy. To czyści kod i lepiej opisuje typ.
xxbbcc
W porządku, ale mój przykład był po prostu hiperbolą. IntStringEnumerator i = new IntStringEnumerator()wciąż jest za dużo pisania.
Blorgbeard wyszedł
9

Skradzione z postu na ten temat w CodingHorror :


Niestety, ty i wszyscy inni źle to zrozumieliście. Chociaż zgadzam się z tobą, że redundancja nie jest dobrą rzeczą, lepszym sposobem rozwiązania tego problemu byłoby zrobienie czegoś takiego:

MyObject m = new ();

Lub jeśli przekazujesz parametry:

Osoba p = nowa („FirstName”, „LastName);

Gdzie podczas tworzenia nowego obiektu kompilator określa typ z lewej strony, a nie z prawej. Ma to inne zalety w porównaniu z „var”, ponieważ może być również użyte w deklaracjach polowych (istnieją również inne obszary, które mogą być przydatne, ale nie będę się tutaj zajmował).

Ostatecznie nie miało to na celu zmniejszenia nadmiarowości. Nie zrozum mnie źle, „var” jest BARDZO ważne w C # dla anonimowych typów / projekcji, ale użycie tutaj jest po prostu DALEKIE (i mówiłem to od dłuższego czasu), ponieważ zaciemniasz typ, który jest używany. Konieczność dwukrotnego wpisania jest zbyt często, ale deklarowanie go zero razy to za mało.

Nicholas Paldino .NET / C # MVP w dniu 20 czerwca 2008 08:00


Sądzę, że jeśli Twoim głównym zmartwieniem jest pisanie mniej - nie ma żadnego argumentu, który mógłby cię zniechęcić do korzystania z niego.

Jeśli kiedykolwiek będziesz tylko osobą, która patrzy na twój kod, to kogo to obchodzi? W przeciwnym razie, w takim przypadku:

var people = Managers.People

jest w porządku, ale w takim przypadku:

var fc = Factory.Run();

powoduje zwarcie wszelkich natychmiastowych dedukcji typu, które mój mózg mógłby zacząć formować z „angielskiego” kodu.

W przeciwnym razie skorzystaj z najlepszej oceny i zaprogramuj „uprzejmość” w stosunku do innych osób, które mogą być zmuszone do pracy nad Twoim projektem.

Rostov
źródło
4
Twoje powyższe przykłady nie są argumentem za niestosowaniem var; są argumentem za użyciem dobrych opisowych nazw zmiennych. Jeśli zamiast [var fc = Factory.Run ();] miałeś [bool fc = Factory.Run ();], kod nie stałby się bardziej przejrzysty.
Ryan Lundy,
9

Za pomocą var zamiast wyraźnego typu znacznie ułatwia refaktoryzację (dlatego muszę zaprzeczyć poprzednim plakatom, które oznaczały, że nie robiło to różnicy lub że był to wyłącznie „cukier składniowy”).

Możesz zmienić typ zwracanych metod bez zmiany każdego pliku, w którym ta metoda jest wywoływana. Wyobrażać sobie

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

który jest używany jak

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

Jeśli chcesz refaktoryzować, SomeMethod()aby zwrócić IEnumerable<MySecondClass>, musisz zmienić deklarację zmiennej (również wewnątrzforeach ) w każdym miejscu, w którym użyłeś metody.

Jeśli napiszesz

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

zamiast tego nie musisz tego zmieniać.

MartinStettner
źródło
zgodził się - zastanawiając się, dlaczego ten miły efekt uboczny nie jest reklamowany tak często, jak niektóre inne, bardziej subiektywne zalety w bardziej popularnych odpowiedziach.
fieldingmellish
Zdarzyło mi się dzisiaj. Mam klasę fabryczną, która zwraca istnienie klasy MainMenu. Dzisiaj stworzyłem MainMenu2 z tym samym interfejsem MainMenu. Po zmianie mam cały kod aplikacji nietknięty!
Marco Staffoli,
8

@aku: Jednym z przykładów są recenzje kodu. Innym przykładem są scenariusze refaktoryzacji.

Zasadniczo nie chcę iść na pisanie na klawiaturze za pomocą myszy. Może nie być dostępny.

erlando
źródło
2
To interesujące, że tak mówisz, ponieważ var może uprościć refaktoryzację. Jeśli użyłeś var, nie musisz. Teraz zawsze możesz polegać na narzędziach refaktoryzacyjnych IDE, ale wiesz, zawsze możesz polegać również na IDE dla tego typu :)
Fred
8

To kwestia gustu. Całe to zamieszanie związane z typem zmiennej znika, gdy przyzwyczajasz się do dynamicznie wpisywanych języków. To znaczy, jeśli kiedykolwiek zaczniesz je lubić (nie jestem pewien, czy wszyscy mogą, ale tak).

C # varjest całkiem fajny, ponieważ wygląda jak pisanie dynamiczne, ale w rzeczywistości jest pisanie statyczne - kompilator wymusza prawidłowe użycie.

Typ twojej zmiennej nie jest tak naprawdę ważny (zostało to powiedziane wcześniej). Powinno być względnie jasne z kontekstu (jego interakcji z innymi zmiennymi i metodami) i jego nazwy - nie oczekuj, że lista klientów zawiera int...

Nadal czekam, aby zobaczyć, co mój szef myśli o tej sprawie - mam koc „śmiało”, aby używać nowych konstrukcji w 3.5, ale co zrobimy z konserwacją?

Daren Thomas
źródło
7

W porównaniu pomiędzy IEnumerable<int>i IEnumerable<double>nie musisz się martwić - jeśli podasz niewłaściwy typ, kod i tak się nie skompiluje.

Nie ma obaw o bezpieczeństwo typu, ponieważ nievar jest dynamiczne. To tylko magia kompilatora i wszelkie niebezpieczne połączenia, które wykonasz, zostaną złapane.

Var jest absolutnie potrzebny Linq:

var anonEnumeration =
    from post in AllPosts()
    where post.Date > oldDate
    let author = GetAuthor( post.AuthorId )
    select new { 
        PostName = post.Name, 
        post.Date, 
        AuthorName = author.Name
    };

Spójrzmy teraz na anonEnumeration w intellisense, a pojawi się coś podobnegoIEnumerable<'a>

foreach( var item in anonEnumeration ) 
{
    //VS knows the type
    item.PostName; //you'll get intellisense here

    //you still have type safety
    item.ItemId;   //will throw a compiler exception
}

Kompilator C # jest dość sprytny - typy anonów generowane osobno będą miały ten sam wygenerowany typ, jeśli ich właściwości będą pasować.

Poza tym, o ile masz inteligencję, sensowne jest używanie varwszędzie tam, gdzie kontekst jest jasny.

//less typing, this is good
var myList = new List<UnreasonablyLongClassName>();

//also good - I can't be mistaken on type
var anotherList = GetAllOfSomeItem();

//but not here - probably best to leave single value types declared
var decimalNum = 123.456m;
Keith
źródło
Proszę się pozbyć IQueriable<T>przed iteracją: anonEnumeration.ToList();
David Diez
@DavidDiez czy mógłbyś zmienić sformułowanie? Twoje oświadczenie nie ma sensu. Żaden fragment mojego kodu nie zawiera odniesienia IQueryableani.ToList()
Keith,
var anonEnumeration = from post in AllPosts() where post.Date > oldDate let author = GetAuthor( post.AuthorId ) select new { PostName = post.Name, post.Date, AuthorName = author.Name };nie zwraca IQueriable<T>?
David Diez
1
@DavidDiez to zależy od tego, co AllPosts()zwraca - pytający odnosi się, List<T>więc założyłem, że. W takim przypadku wynikiem anonEnumerationbędzie typ IEnumerable<'a>. Teraz, jeśli zamiast tego nastąpi AllPosts()zwrot, IQueryable<T>to anonEnumerationstanie się IQueryable<'a>(uwaga nie iw Queryable) - jednak w takim przypadku mój kod nadal działa, ponieważ IQueryable<T>implementuje IEnumerable<T>. Jest mnóstwo lepszych pytań i odpowiedzi na temat różnic między nimi - tutaj mój przypadek 'ajest anonimowy i varpozwala przypisać go do zmiennej o typie statycznym.
Keith,
Och, rozumiem, dzięki za wyjaśnienie :) Mój komentarz był taki, że iteracja an IQueryable<T>nie jest dobrą praktyką, ponieważ w każdej iteracji robisz instrukcję read w DB. Pamiętaj, aby to zrobić *.ToList() IQueryable<T>przed iteracją
David Diez
7

Myślę, że to zależy od twojej perspektywy. Osobiście nigdy nie miałem trudności ze zrozumieniem fragmentu kodu z powodu var„niewłaściwego użycia”, a moi współpracownicy i ja używam go dość często. (Zgadzam się, że Intellisense jest pod tym względem ogromną pomocą.) Z zadowoleniem przyjmuję to jako sposób na usunięcie powtarzającego się cruftu.

W końcu, jeśli stwierdzenia lubią

var index = 5; // this is supposed to be bad

var firstEligibleObject = FetchSomething(); // oh no what type is it
                                            // i am going to die if i don't know

gdyby naprawdę nie można było sobie z tym poradzić, nikt nie używałby dynamicznie pisanych języków.

mqp
źródło
Przypuszczalnie w .Net 4, gdzie typami dynamicznymi są wspólne miejsca, czy to stanie się ważniejsze?
Colin Desmond,
2
Wręcz przeciwnie, jeśli teraz mylisz się z „var”, spodziewam się, że dodatkowo będziesz mylić z „dynamiką”. Niech Bóg zabroni, aby ktokolwiek kiedykolwiek zadeklarował dynamikę, a następnie odwołuje się do niej za pomocą „var” :)
mqp
Miałem na myśli coś takiego jak dynamiczny d = 52; var x = d; co powinno być w porządku.
mqp,
7

Używam var tylko wtedy, gdy jest jasne, aby zobaczyć, jaki typ jest używany.

Na przykład użyłbym var w tym przypadku, ponieważ od razu widać, że x będzie typu „MyClass”:

var x = new MyClass();

NIE używałbym var w takich przypadkach, ponieważ musisz przeciągnąć myszą nad kodem i spojrzeć na etykietkę, aby zobaczyć, jaki typ zwraca MyFunction:

var x = MyClass.MyFunction();

Szczególnie nigdy nie używam var w przypadkach, w których prawa strona nie jest nawet metodą, a jedynie wartością:

var x = 5;

(ponieważ kompilator nie może wiedzieć, czy chcę bajt, skrót, int lub cokolwiek)

Christian Specht
źródło
Jeśli prawa strona nie jest wystarczająco jasna, aby uzasadnić użycie var, varoznacza to, że nie ma problemu: problemem jest prawa strona. Nie jest wystarczająco opisowy . Customer c = GetContext()jest nadal niejasne i nie lepsze niż używanie var.
JulianR
6

Dla mnie antypatia do varilustruje, dlaczego dwujęzyczność w .NET jest ważna. Dla programistów C #, którzy również zrobili VB .NET, zalety varsą intuicyjnie oczywiste. Standardowa deklaracja C #:

List<string> whatever = new List<string>();

odpowiada w VB .NET wpisaniu tego:

Dim whatever As List(Of String) = New List(Of String)

Jednak nikt nie robi tego w VB .NET. Byłoby głupio, ponieważ od czasu pierwszej wersji .NET mogłeś to zrobić ...

Dim whatever As New List(Of String)

... który tworzy zmienną i inicjuje wszystko w jednym stosunkowo kompaktowym wierszu. Ach, ale co jeśli chcesz IList<string>, nie List<string>? Cóż, w VB .NET oznacza to, że musisz to zrobić:

Dim whatever As IList(Of String) = New List(Of String)

Tak jak trzeba to zrobić w języku C # i oczywiście nie można użyć vardo:

IList<string> whatever = new List<string>();

Jeśli potrzebujesz, aby ten typ był czymś innym, może być. Ale jedną z podstawowych zasad dobrego programowania jest ograniczenie redundancji i właśnie to robi var.

Ryan Lundy
źródło
1
Zabawne, że wspominasz o dwujęzyczności jako o czymś, co promuje użycie var. Mój antagonizm wobec słowa kluczowego var wynika bezpośrednio z mojej biegłości w javascript! :)
urig
varw C # nie ma żadnego połączenia z varJavaScript. var-Declared zmienna w C # jest silnie wpisany.
Ryan Lundy,
6

Używaj go do anonimowych typów - po to jest. Cokolwiek innego jest zbyt daleko posunięte. Jak wiele osób, które dorastały na C, jestem przyzwyczajony do patrzenia na lewą stronę deklaracji dla tego typu. Nie patrzę na prawą stronę, chyba że muszę. Używanie varjakiejkolwiek starej deklaracji sprawia, że ​​robię to cały czas, co osobiście uważam za niewygodne.

Ci, którzy mówią „to nie ma znaczenia, użyj tego, z czego jesteś zadowolony”, nie widzą całego obrazu. Każdy w pewnym momencie odbierze kod innej osoby i będzie musiał poradzić sobie z wszelkimi decyzjami podjętymi w momencie jej pisania. Wystarczająco źle jest mieć do czynienia z radykalnie odmiennymi konwencjami nazewnictwa lub - klasycznym mankamentem - wzmacniającymi stylami, bez dodawania całej varmieszanki „ albo nie”. Najgorszym przypadkiem będzie sytuacja, w której jeden programista nie używał, vara następnie pojawił się opiekun, który go uwielbia i rozszerza kod przy użyciu. Więc teraz masz bezbożny bałagan.

Standardy są dobrą rzeczą, ponieważ oznaczają, że istnieje większe prawdopodobieństwo, że będziesz w stanie pobrać losowy kod i szybko go odczytać. Im więcej rzeczy się różni, tym trudniej jest. A przejście do stylu „var wszędzie” jest duże różnicę.

Nie mam nic przeciwko pisaniu dynamicznemu i nie mam nic przeciwko wpisywaniu w sposób domyślny - w zaprojektowanych dla nich językach. Bardzo lubię Python. Ale język C # został zaprojektowany jako język o statycznym pisaniu i tak powinien pozostać. Łamanie reguł dla typów anonimowych było wystarczająco złe; pozwalanie ludziom pójść o krok dalej i przełamać idiomy języka jeszcze bardziej, jest czymś, z czego nie jestem zadowolony. Teraz, gdy dżin wyszedł z butelki, nigdy nie wróci. C # zostanie przeniesiony do obozów. Niedobrze.

Neil Hewitt
źródło
7
Łał. Ignorowanie wszystkich argumentów przedstawionych do tej pory w tym wątku i ponowne ustalenie całej dyskusji jest sporym osiągnięciem.
Konrad Rudolph,
Ten 100% opisuje, co myślę o „var”, szczególnie z punktu widzenia wybierania komuś innego kodu. Użycie var radykalnie zmienia dane zadanie, jeśli jest zaśmiecone. +1
Simon
6

Wiele razy podczas testowania mam taki kod:

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

Teraz czasami chcę zobaczyć, co zawiera SomeOtherThing, SomeOtherThing nie jest tego samego typu, co zwraca CallMethod (). Ponieważ używam var, po prostu zmieniam to:

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

do tego:

var something = myObject.SomeProperty.SomeOtherThing;

Bez var musiałbym ciągle zmieniać zadeklarowany typ po lewej stronie. Wiem, że to niewielkie, ale bardzo wygodne.

BFree
źródło
6

Dla entuzjastów, którzy myślą varoszczędzają czas, potrzeba mniejszej liczby naciśnięć klawiszy:

StringBuilder sb = new StringBuilder();

niż

var sb = new StringBuilder();

Policz je, jeśli mi nie wierzysz ...

19 kontra 21

Wyjaśnię, jeśli będę musiał, ale po prostu spróbuj ... (w zależności od aktualnego stanu twojej inteligencji może być konieczne wpisanie kilku kolejnych dla każdego)

Dotyczy to każdego rodzaju, o jakim możesz pomyśleć !!

Moim osobistym odczuciem jest to, że var nie powinien być nigdy używany, chyba że typ nie jest znany, ponieważ zmniejsza on czytelność rozpoznawania w kodzie. Rozpoznanie typu zajmuje więcej czasu niż mózgowi pełnej linii. Dawni timery, którzy rozumieją kod maszynowy i bity, dokładnie wiedzą o czym mówię. Mózg przetwarza równolegle, a kiedy używasz var, zmuszasz go do szeregowania danych wejściowych. Dlaczego ktokolwiek miałby chcieć, aby ich mózg pracował ciężej? Po to są komputery.

Wray Smallwood
źródło
Uważam, że powtarzanie stringBuilder sb = new StringBuilder () jest bałaganiarskie i dłużej, aby wyraźnie je rozpoznać. To dodatkowy hałas. Problem polega na tym, że określenie, co robi, a co nie stanowi dodatkowego wysiłku intelektualnego, aby zrozumieć jakiś kod, jest dość subiektywne!
ljs
„var nie powinien być nigdy używany, chyba że typ nie jest znany ...” - ZAWSZE możesz znać typ, podobnie jak kompilator. To nie jest dynamiczne pisanie, po prostu pozwala kompilatorowi określić typ dla ciebie. Ale ten typ nigdy nie jest nieznany.
Gabriel Magana
5

Dzielę var na wszystkie miejsca, jedyne wątpliwe miejsca dla mnie to wewnętrzne typy krótkie, np. Wolę int i = 3;więcejvar i = 3;

robi-y
źródło
5

Z pewnością może to uprościć, z kodu, który napisałem wczoraj:

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

Bez tego byłby to bardzo gadatliwy var.

Dodatek: Trochę czasu spędzonego na języku z wnioskowaniem typu rzeczywistego (np. F #) pokaże, jak dobre są kompilatory w poprawnym typowaniu wyrażeń. Z pewnością oznaczało to, że zwykle używam vartyle, ile mogę, a użycie jawnego typu wskazuje teraz, że zmienna nie jest typu wyrażenia inicjującego.

Richard
źródło
Tak, kompilatory są mądrzejsze od nas, zrób to!
Benjol,