Dlaczego ReSharper chce używać „var” do wszystkiego?

214

Właśnie zacząłem używać ReSharpera z Visual Studio (po wielu zaleceniach dotyczących SO). Aby to wypróbować, otworzyłem najnowszy projekt ASP.NET MVC. Jedną z pierwszych i najczęstszych rzeczy, które zauważyłem, sugeruje to zmianę większości / wszystkich moich wyraźnych deklaracji na var. Na przykład:

//From This:
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
//To This:
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

i tak dalej, nawet z typów prostych, takich jak int, boolitp

Dlaczego jest to zalecane? Nie wywodzę się z informatyki ani środowiska .NET, ponieważ ostatnio „wpadłem” w rozwój .NET, więc naprawdę chciałbym zrozumieć, co się dzieje i czy jest to korzystne, czy nie.

Chris
źródło
27
Myślałem o tym przez jakiś czas i doszedłem do wniosku, że powinienem zawsze używać var, nawet jeśli ten typ nie jest wcale oczywisty! Powodem jest to, że zmusza mnie do wybrania najbardziej opisowej nazwy, jaką mogę wymyślić, i ostatecznie sprawia, że ​​kod jest znacznie, znacznie bardziej czytelny. Ostatecznie pomaga także oddzielić logikę od implementacji. Oczywiście to tylko moja opinia, mam nadzieję, że komuś to pomoże;).
MasterMastic 30.01.2013

Odpowiedzi:

189

Jednym z powodów jest poprawiona czytelność. Który jest lepszy?

Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();

lub

var dictionary = new Dictionary<int, MyLongNamedObject>();
Mark Sherretta
źródło
260
Powiedziałbym pierwszy. Łatwiej zobaczyć, co się dzieje!
Mongus Pong,
104
Grzyb: Czy lubisz Czy podoba Ci się Redundant Text Redundant Text? : D
Mark Simpson,
73
Moim zdaniem wyrażanie się jest wyraźniejsze. Używanie var do dużo powoduje ból głowy w niektórych scenariuszach.
user1231231412,
172
Nienawidzę, kiedy deweloperzy używać vardo wszystkiego - zrobić wiele, wiele opinii kod za pomocą TFS (dyferencjału webowy) i to sprawia, że moje zadanie niezwykle trudne: tj var items = GetSomeItems();vs IDataReader dr = GetSomeItems();Brakujące za pomocą komunikatu na obu, ale łatwiej mi się złapać podczas korzystania IDataReadervs var.
Chris Gessler
17
jeśli jesteś dobrym programistą piszącym dobry kod i korzystasz z biblioteki takiej jak Resharper, nie musisz znać jawnego typu, z którym masz do czynienia. Podobnie jak wtedy, gdy używasz interfejsów do deklarowania umowy, ale nie konkretnej klasy, var pozwala ci powiedzieć, że nie obchodzi cię, jaki jest zwracany „typ”, obchodzi cię tylko to, co robi, i używając dobrze nazwanych zmiennych, wraz dzięki asystentom intelli-sense & resharper / VS (takim jak CTRL + KLIKNIJ, aby przejść do definicji) dostaniesz 99% możliwości. Dodatkowo użycie var oznacza, że ​​nie muszę przepisywać mojej bazy kodu, jeśli zmienię typ zwracanej metody.
Joshua Barker
286

To, co sugeruje ReSharper, to wyraźnie nadużywanie słowa kluczowego var. Możesz go użyć, gdy typ jest oczywisty:

var obj = new SomeObject();

Jeśli ten typ nie jest oczywisty, powinieneś go zapisać:

SomeObject obj = DB.SomeClass.GetObject(42);
Guffa
źródło
36
Aby zagrać w adwokata diabłów, być może jeśli typ nie jest jasny z metody lub nazwy zmiennej, oznacza to problem z nazywaniem czegoś więcej niż nadużywaniem var. Zgadzam się jednak zasadniczo, że var należy stosować tylko wtedy, gdy nie usuwa ono przejrzystości.
Matt Briggs,
33
W tym przypadku wolałbym używać lepszych nazw zmiennych. Zasadniczo proponujesz, abyśmy spojrzeli w górę, gdzie zmienna jest zdefiniowana, aby dowiedzieć się, jaki typ - proponuję, abyśmy nazwali zmienne lepiej, abyśmy znali cel zmiennej od razu.
Jaco Pretorius,
18
@Jaco: +1, ale warto wspomnieć, że nie zaleca się podawania informacji o typie w nazwie zmiennej. Na przykład notacja węgierska nie jest uważana za dobrą praktykę.
Roman Boiko,
8
To, czy domyślne ustawienia ReSharpera są nadużywane, varjest kwestią opinii, a nie „wyraźnie” jednej czy innej rzeczy. Wolę nie wpisywać rzeczy, które kompilator może sam wymyślić. Lubię wnioskowanie typu C # i często żałuję, że nie było tak dobre jak wnioskowanie typu F #. Gdybym mógł, pomijałbym typy jawne z parametrów metody i typy zwracane, jak to jest normą w F #. Oczywiście nie wszyscy się zgadzają.
Joel Mueller,
15
@AnonymousType: Nadal brakuje ci punktu. Powiedziałeś, że nazwy metod powinny zawsze odzwierciedlać intencje metody, ale nawet jeśli tak, nie oznacza to, że nazwa określa typ zwracanej wartości. Na przykład metoda odczytu z Streamobiektu nosi nazwę Read, a nie nazwę ReadAndReturnNumberOfBytesAsInt32.
Guffa,
99

Osobiście wolę wyłączyć tę sugestię. Korzystanie varmoże często poprawić czytelność; ale, jak wspomniałeś, czasami go zmniejsza (w przypadku prostych typów lub gdy typ wynikowy jest niejasny ).

Wolę wybierać, kiedy używam, vara kiedy nie. Ale znowu, to tylko ja.

Bryan Menard
źródło
11
Myślałem, że ReSharper miał być całkiem sprytny; Czy nie powinno być wystarczająco mądre, aby wiedzieć, kiedy wynikowy typ jest oczywisty (np. Cokolwiek z nowym słowem kluczowym), a kiedy nie jest oczywisty?
DisgruntledGoat,
3
Cóż, nie znam szczególnych cech tej funkcji, ale jestem pewien, że byłem przytłoczony ilością podanych sugestii; I też używam vardość często.
Bryan Menard,
5
Dowiedziałem się, że kiedy zawsze używasz var (jak sugeruje resharper), wymusza to prawidłowe nazwanie zmiennych.
Sauleil 28.01.11
Czy możesz wyłączyć sugestię?
Chris S
@AngeDeLaMort: chodzi o to, że zmusza cię do używania niewłaściwych nazw, np var methodXYResultIntArray. Jest to niezgodne ze wszystkimi standardami kodowania i mniej zwięzłe niż int[] methodXYResult. Jeśli chcesz zwrócić a byte[]z metody w przyszłości, wszystkie nazwy zmiennych są niepoprawne. W przypadku jawnych typów można to bardzo łatwo zmienić. Istnieją powody do użycia var, na przykład z Dictionary<string, List<SomeType<int>>>. Ale jeśli nazwa pełnego typu nie jest zbyt długa i nie używasz jej newpo prawej stronie (lub w jawnej obsadzie) resharper nie powinien jej sugerować.
Tim Schmelter
69

varmoże zwiększyć czytelność kodu, jednocześnie zmniejszając natychmiastowe zrozumienie kodu. Podobnie może zmniejszyć czytelność kodu w innych sytuacjach. Czasami jego użycie jest neutralne. Miara czytelności rozumienia nie jest proporcjonalna, ale zależy od sytuacji. Czasami oba są zwiększane lub zmniejszane razem.

Czynnikiem jest to var, co jest stosowane i jak dobrze cel obsługuje natychmiastowe zaciemnianie swojego typu danych do czytnika, lub czy informacja o jego typie jest potrzebna do zrozumienia dostępnej części programu.

Na przykład złe nazewnictwo może prowadzić do varzmniejszenia zrozumienia kodu. Nie jest to jednak varwina:

var value1 = GetNotObviousValue(); //What's the data type? 
//vs. 
var value2 = Math.Abs(-3); // Obviously a numeric data type. 

Czasami nie ma sensu używać varprostych typów danych, gdy kod jest bardziej czytelny w przypadku jego braku:

var num = GetNumber(); // But what type of number?
// vs. 
double num = GetNumber(); // I see, it's a double type. 

Czasami varmoże być przydatne ukrycie informacji o typie danych, których niekoniecznie zależy Ci na złożoności:

    IEnumerable<KeyValuePair<string,List<Dictionary<int,bool>>>> q = from t in d where t.Key == null select t; // OMG! 
    //vs. 
    var q = from t in d where t.Key == null select t;

    // I simply want the first string, so the last version seems fine.  
    q.First().Key; 

Państwo musi wykorzystać var, gdy pojawia się anonimowy typ obecny, ponieważ nie ma nazwa typu nazwać to przez:

var o = new { Num=3, Name="" };

Jeśli mimo to Visual Studio Intellisense dostarcza informacje o typie var, musisz mniej polegać na swoim zrozumieniu dzięki ścisłemu odczytywaniu kodu bez pomocy. Prawdopodobnie rozsądnie jest założyć, że nie każdy może mieć Intellisense lub go używać.

Podsumowując na podstawie powyższych przykładów, sugeruję, że stosowanie carte blanche varnie jest dobrym pomysłem, ponieważ większość rzeczy najlepiej jest wykonywać z umiarem i na podstawie okoliczności, jak pokazano tutaj.

Dlaczego Resharper używa go domyślnie? Sugeruję z łatwością, ponieważ nie można przeanalizować niuansów sytuacji, aby zdecydować, kiedy najlepiej jej nie używać.

John K.
źródło
5
IMHO twoje przykłady są właściwie dobrym powodem do użycia var, zmusi cię to do napisania przyzwoitych nazw metod. GetNumber() -but what type?- cóż, dlaczego cię to obchodzi? Jeśli ważne jest, aby wiedzieć, należy wywołać metodę GetNumberAsDouble(), to jest tak samo jasne i zadziała, jeśli jedna metoda zwraca stringi jedną zwraca double.
nicodemus13
10
@ nicodemus13 Na ogół wiesz, kiedy zależy Ci na typie zwracanym przez funkcję, kiedy faktycznie używasz wartości zwracanej, a nie kiedy piszesz samą funkcję. Twój sugerowany schemat nazewnictwa może prowadzić do nadużyć, takich jak GetResultsAsIEnumerableOfDouble, a wszystko, co robi, to przesuwanie informacji o typie, które usunąłeś z lewej strony przypisania, przy użyciu var na prawej stronie przypisania.
Eric
var value2 = Math.Abs ​​(-3); // Oczywiście liczbowy typ danych. Przepraszam, nie zgadzam się z tym całkowicie, biorąc pod uwagę, że metoda Abs ma 7 przeciążeń, które prowadzą do nic innego, jak tylko niejasności, gdy na to patrzymy, imo
s1cart3r
var może również prowadzić do subtelnych błędów logicznych, takich jak: var counter = "0"; kiedy chcesz to liczba całkowita.
alaniane
42

W ReSharper (8.02, ale prawdopodobnie w innych wersjach) opcję sugestii „Użyj niejawnie wpisanej zmiennej lokalnej” można dostosować do własnych preferencji , cokolwiek to może być, najpierw otwierając menu opcji dla ReSharper:

Menu opcji ReSharper

Następnie w obszarze „Kontrola kodu” poprzez dostosowanie „Ważności kontroli” wybranego języka, w moim przypadku c #:

Wyłącz domyślnie wpisaną zmienną lokalną

Jak widać, istnieją opcje dostosowania wszystkich sugestii ReSharper. Ma nadzieję, że pomoże to komuś takiemu jak ja, który ma już strategię użytkowania „var” i chce, aby ReSharper ją przestrzegał :)

Erikest
źródło
Odpowiada to na inne pytanie, które w ogóle nie zostało zadane.
Carles Alcolea
9
Ale ma to znaczenie dla wielu, którzy szukają go, gdy tu dotrą. +1
Ori Nachum
24

Dziwi mnie, że nikt nie wspominał, że łatwiej jest również zmienić typ tworzonego obiektu, ponieważ

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

jest formą powtórzenia . Jeśli chcę zmienić się AVeryLongTypeNamew jedną z jego klas pochodnych, potrzebuję zmienić to tylko raz podczas korzystania vari nadal mam dostęp do metod klas potomnych.

Poza tym ważna jest poprawiona czytelność, ale jak powiedzieli inni, var nie powinien być nadużywany, więc myślę, że wyłączenie podpowiedzi w Resharper jest absolutnie w porządku.

Philipp
źródło
Bardzo przydatne, gdy nazywa się metody fabryczne, a nie „nowe”
Ian Ringrose,
Jeśli musisz użyć „MyClass” podczas pisania kodu i działa, to działa. Kiedy musisz go zmienić, musisz iść i zmieniać go wszędzie, szczególnie gdy masz zaangażowane interfejsy. Kod nie powinien być traktowany jak esej, powinien być semantyczny i dobrze zdefiniowany.
Piotr Kula,
24

„var” polega na jasności

Główna debata na temat tego, czy użyć varsłowa kluczowego, czy nie, dotyczy tego, jak czytelny jest kod dla ciebie i innych programistów.

Tak, jakbyś pisał historię, nie ma ostatecznej właściwej odpowiedzi. Ale spójrzmy na kilka przykładów tego w prostym języku angielskim.

Jake przywitał się z Billem. Nie lubił go, więc odwrócił się i poszedł w drugą stronę.

Kto poszedł w drugą stronę? Jake czy Bill? W tym przypadku użycie nazw „Jake” i „Bill” przypomina użycie nazwy typu. A „On” i „on” jest jak użycie varsłowa kluczowego. W takim przypadku może być bardziej szczegółowe. Poniższe na przykład jest znacznie jaśniejsze.

Jake przywitał się z Billem. Jake nie lubił Billa, więc odwrócił się i poszedł w drugą stronę.

W tym przypadku bardziej szczegółowe uściśliło zdanie. Ale nie zawsze tak będzie. W niektórych przypadkach dokładność utrudnia czytanie.

Bill lubi książki, więc Bill poszedł do biblioteki, a Bill wyjął książkę, którą Bill zawsze lubił.

W takim przypadku łatwiej byłoby odczytać zdanie, gdybyśmy użyli słowa „on”, a w niektórych przypadkach całkowicie pominęli jego imię, co jest równoważne użyciu varsłowa kluczowego.

Bill lubi książki, więc poszedł do biblioteki i wyjął książkę, którą zawsze lubił.

Te przykłady obejmują sedno, ale nie opowiadają całej historii. W tych przykładach był tylko jeden sposób na odniesienie się do osoby. Albo używając ich nazwy, albo używając bardziej ogólnego terminu, takiego jak „on” i „on”.

W przypadku kodu mamy 3 sposoby na zwiększenie przejrzystości. Typ, nazwa zmiennej i przypisanie. Weźmy na przykład następujący wiersz kodu:

Person p = GetPerson();

Teraz pojawia się pytanie, czy w tym wierszu kodu jest wystarczająco dużo informacji, aby pomóc ci zrozumieć, co się dzieje?

Co z następującym wierszem kodu? Czy nadal wiesz, co poznacza w tym przypadku:

var p = GetPerson();

A teraz:

var p = Get();

Lub teraz:

var person = Get();

Albo ten:

var t = GetPerson();

Albo to:

var u = Person.Get();

To, czy słowo kluczowe vardziała w danym scenariuszu, zależy w dużej mierze od kontekstu kodu, takiego jak nazwy zmiennych, klas i metod. Zależy to również od złożoności kodu i reszty otaczającego go kodu.

Osobiście lubię używać varsłowa kluczowego, które jest dla mnie bardziej wszechstronne . Ale mam też tendencję do nazywania moich zmiennych po typie, więc tak naprawdę nie tracę żadnych informacji.

To powiedziawszy czasami w zależności od kontekstu, z którego robię wyjątki, taka jest natura wszystkiego złożonego, a oprogramowanie jest niczym, jeśli nie złożone.

Luis Perez
źródło
1
Najbardziej podoba mi się ta odpowiedź, ponieważ nie mam nic przeciwko, varo ile wiem, co to jest, czytając ten wiersz. Jeśli nie mam pojęcia, co zwraca metoda z innego rozwiązania korzystającego z innego modelu domeny, wolę wyraźnie zdefiniować ten typ, co znacznie ułatwia czytanie. +1
Piotr Kula,
We wszystkich przypadkach, w których zwracany typ nie jest oczywisty, zgadzam się, że nie powinieneś używać var, ponieważ teraz pomijasz przydatne informacje.
rzuca
18

Też mi się nie podobało.

Nie chcę, aby przerodziło się to w debatę na temat wykorzystania var, ma swoje zastosowania, ale nie powinno być stosowane wszędzie.

Najważniejszą rzeczą do zapamiętania jest to, że ReSharper jest skonfigurowany zgodnie z dowolnymi standardami kodowania.

Edycja: ReSharper i var

LiamB
źródło
13
Po około roku oporu prawie zawsze używam teraz var.
LiamB,
15

Widzę wiele poprawnych odpowiedzi, ale brakuje pełnej.

Prawdą jest, że ReSharper vardomyślnie nadużywa . Myślę, że większość ludzi się z tym zgodzi. Łatwiej jest również odczytać, kiedy varjest używany, a typ jest oczywisty, na przykład przy użyciu newinstrukcji. Widziałem jeden post, który pokazał, jak zaktualizować ważność inspekcji, aby pokazać tylko wskazówki dotyczące użycia var.

Próbowałem najpierw skomentować inne posty, aby dodać, gdzie je ustawić, ale nie miałem na to reputacji. Najwyraźniej nie miałem reputacji, aby opublikować zrzut ekranu z ustawieniami.

Wyjaśnię ci, jak się tam dostać.

W Visual Studio> Menu główne> Resharper> Opcje> Edycja kodu> C #> Styl kodu> Wykorzystanie Var w deklaracjach

  • Dla typów wbudowanych Użyj jawnego typu
  • Dla prostych typów Użyj „var”, gdy jest to widoczne
  • Gdzie indziej użyj „var ”

wprowadź opis zdjęcia tutaj

Dokumentacja pomocy ReSharper: Styl składni kodu: Wpisywanie niejawne / jawne (słowo kluczowe „var”) - Konfiguracja preferencji dotyczących używania słowa kluczowego „var”

Nathan Kovac
źródło
To powinno być oznaczone jako poprawna odpowiedź poza debatami var, jest to zrównoważone podejście
Brian Ogden
Czy możesz podać przykład, w jaki sposób decyduje się „gdzie oczywiste”?
rzuca
13

Moja zasada jest taka:

  • Ty deklarując prymitywny typ (czyli byte, char, string, int[], double?, decimal, itd.)? -> Użyj typu:

    string myStr = "foo";
    int[] myIntArray = [123, 456, 789];
    double? myDouble = 123.3;
  • Czy deklarowania typu złożonego (czyli List<T>, Dictionary<T, T>, MyObj)? -> Użyj var:

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();
Sumner Evans
źródło
Chciałbym się nie zgodzić, string myStr = "foo";to oczywiste, że to struna. Umieściłbym wszystkie twoje przykłady w kategorii use var ... i deklaracje, które są zwrotami z metody użycia typu explicity. Ale pod koniec dnia wszystko, co Ty i Twój zespół czuje, jest lepsze dla danego projektu.
Dean Meehan,
12

Chciałbym tylko wskazać, że użycie „var” jest zalecane w konwencjach kodowania C #

gdy typ zmiennej jest oczywisty z prawej strony przypisania lub gdy dokładny typ nie jest ważny

prawdopodobnie dlatego końcówka jest domyślnie włączona w ReSharper. Udostępniają również niektóre przypadki, w których nie poprawiłoby to czytelności poniżej w tym samym dokumencie.

jose
źródło
To wspaniale, gdy wiesz, że typ pochodzi System.Diagnostics.PerformanceCounter() - Możesz łatwo odróżnić licznik wydajności od wbudowanej klasy diagnostycznej. Ale jaki typ jest tutaj zwracany? var thingyMaBob = GetThatSpecialThing(18,null,(MyEnum)2)? Brak wskazówek dotyczących taktowania, szczególnie jeśli masz w swoim rozwiązaniu ponad 100 projektów.
Piotr Kula,
„Zalecane, gdy typ zmiennej jest oczywisty” oraz „Podają również niektóre przypadki, w których nie poprawiłoby to czytelności poniżej w tym samym dokumencie”. Szczerze mówiąc, myślę, że przegapiłem twój punkt. Moja odpowiedź mówi to samo, co mówisz.
jose
6

ReSharper zaleca, varponieważ ma tendencję do rozplątywania tworzenia obiektów.

Porównaj te dwa przykłady:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

To tylko skrót, który powinien być łatwiejszy do odczytania.

Myślę, że to w porządku, gdy tworzysz nowe obiekty jawnie za pomocą „new”. W twoim przykładzie może nie być jednak oczywiste, czy klasy nie zostały poprawnie nazwane.

Paul Sasik
źródło
6

BTW, ReSharper rozróżnia „możesz zastosować tę sugestię do swojego kodu” i „Twój kod jest zepsuty, czy chcę to naprawić?”. Słowo varkluczowe znajduje się w kategorii sugestii, podobnie jak „odwróć, jeśli chcesz ograniczyć zagnieżdżanie”; nie musisz tego przestrzegać.

Możesz skonfigurować, jak denerwujące są poszczególne alerty, w oknie dialogowym Opcje lub bezpośrednio w menu podręcznym tego alertu. Możesz obniżyć liczbę rzeczy takich jak varsugestia, aby były mniej widoczne, lub możesz ulepszyć takie rzeczy, jak alert „użyj metody rozszerzenia”, aby wyświetlał się jako rzeczywisty błąd.

Tim Robinson
źródło
5

varCechą .NET 3.0 jest po prostu rodzaj wnioskowania , która jest typu bezpieczne i często sprawia, że kod łatwiejsze do odczytania. Ale nie musisz i możesz wyłączyć tę rekomendację w resharper, jeśli chcesz.

Klaus Byskov Pedersen
źródło
4

Var jest niesamowity! Natknąłem się na wielu programistów, którzy mają wrażenie, że varjest związany z typem dynamicznym, tak nie jest. Nadal jest statycznie wpisany, po prostu decyduje o tym kompilator.

Oto kilka niesamowitych zalet używania var

Mniej pisania var jest krótsze i łatwiejsze do odczytania, na przykład

Dictionary<int,IList<string>> postcodes = new Dictionary<int,IList<string>>()Fuj.

var postcodes = new Dictionary<int,IList<string>>()\ o / \ o /

Bardziej opisowe nazwy zmiennych - niepewne, ale myślę, że ważne jest, aby pozwolić vartutaj zabłysnąć płynnej naturze . Jak varjest nieco niejasne, to naprawdę nie zachęcają bardziej desciptive nazwę zmiennej zamiast pozwalając Czytaj typ dla siebie.

Mniej zmian kodu - jeśli zmieni się typ zwracanego wywołania metody. Musisz tylko zmienić wywołanie metody, a nie każde używane miejsce.

Typy anonimowe - typy anonimowe to naprawdę potężna koncepcja, szczególnie w obszarach takich jak częściowe zasoby WebApi . Bez var nie można ich używać.

Czasami jednak użyteczne jest jawne deklarowanie typów i uważam to za najbardziej przydatne w operacjach podstawowych lub strukturach. Na przykład osobiście nie uważam tej składni za bardzo przydatną:

for(var i = 0; i < 10; i++) 
{

}

vs

for(int i = 0; i < 10; i++) 
{

}

Wszystko varzależy od osobistych preferencji, ale używanie naprawdę przyspieszy rozwój i odblokuje cały świat dobroci typu anonimowego.

KnowHoper
źródło
2

Nie ma różnicy technicznej, jeśli użyjesz var, typ jest sugerowany przez kompilator. Jeśli masz taki kod:

var x = 1;

x jest implikowane jako int i nie można mu przypisywać żadnych innych wartości.

Słowo kluczowe var jest przydatne, jeśli zmienisz typ zmiennej; musisz tylko wprowadzić jedną zmianę zamiast dwóch:

var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";
eWolf
źródło
1
@AlexKamburov kod 10 linii poniżej i tak się zepsuje, nie jest związany z var.
user3285954
1
@ user3285954 W niektórych przypadkach var może ukryć problem i wtedy rzeczy mogą stać się brzydkie. Problemem nie jest pisanie kodu, problemem jest konserwacja. Niektórzy twierdzą, że var jest czystszy, ale czasami widzę to jako zaciemnienie. Jest blisko debaty religijnej. brad-smith.info/blog/archives/336 Osobiście używam var tylko do instrukcji Linq i innych miejsc, w których deklarowanie typu jest naprawdę pełne. Myślę, że var jest dobrym dodatkiem i ludzie muszą obserwować komentarze Andersa Hejlsberga na temat powodów jego wprowadzenia.
Alex Kamburov
2

Słowo varkluczowe zostało wprowadzone w C # 3.0 - pozwala nam zapomnieć o wyraźnym określeniu naszego typu.

Nie ma żadnej różnicy w tym, czy używasz

MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

lub

var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

oprócz czystej czytelności i mniejszej szansy na błąd.

Wygląda to na stereotypowy przykład, ale powiedz, że poniższe informacje mogą pomóc w zrozumieniu:

var myInt = 23;

zwraca inttyp, natomiast

var myInt = "23";

zwraca stringtyp.

Odniesienie MSDN

Daniel May
źródło
2

Określenie jawnego typu obiektu jest w jakiś sposób zbędne. Nawet przetłumaczony na angielski, brzmi to nadmiarowo: „umieść obiekt typu X w zmiennej typu X” vs „Umieść obiekt typu X w zmiennej”.

Jednak używanie „var” ma swoje ograniczenia . Zapobiega poniższemu wykorzystaniu polimorfizmu, który jest czystym pięknem :

Załóżmy, że pies rozszerza zwierzę; Cat rozszerza hierarchię klas zwierząt:

Animal x = new Dog();
DoStuffWithDog(x as Dog);

x = new Cat();
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

Ten sam kod z x zadeklarowanym za pomocą „var” nie będzie się kompilował .

var x = new Dog(); // from this point, x is a Dog
DoStuffWithDog(x as Dog);

x = new Cat(); // cannot assign a Cat instance to a Dog
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

W każdym razie, wracając do pierwotnego pytania, nie używam Resharpera, ale zakładam, że jest wystarczająco inteligentny, aby wykryć, kiedy nie używać „var”. :-)

xtrem
źródło
4
Niepotrzebne rzucanie (z as) jest okropne. Błędy kompilacji zamieniasz w błędy środowiska wykonawczego, jeśli masz coś takiego: Animal x = new Cat(); DoStuffWithDog(x as Dog); Dlaczego ponownie użyć x? Pies x = nowy pies (), kot y = nowy kot (), boom nie jest już możliwy.
Mark Sowul,
rzutowanie (z „as” lub nie) może spowodować błąd w czasie wykonywania. Co jest takiego „okropnego” w castingu, kiedy wiesz, co robisz? Dlaczego ponownie użyć X? Przykład tutaj jest ilustracyjny. Celem tego przykładu jest pokazanie, w jaki sposób użycie „var” może powodować ograniczenia, gdy odniesienie ma być polimorficzne.
xtrem,
5
Nie, nie może: polimorfizm jest przeciwieństwem tego, co się tutaj dzieje. To próbuje przekazać obiekty typu Animaldo metod, które pobierają Dogi Cat. Polimorfizm jest odwrotna: tak można przekazać obiekty typu Dogi Catdo metody, które ma Animal, na przykład void Walk(Animal a): Walk(new Cat()),Walk(new Dog())
Mark Sowul
Nie powinieneś ponownie używać zmiennych w ten sposób, prowadzi to do bardzo nieprzyjemnych błędów. Nie jest to tak oczywiste w krótkich metodach, ale kiedy masz 15-20 linii kodu, zapomnisz, czym jest x. Nie bądź leniwy: var dog = new Dog (); DoStuff (pies); var cat = new Cat (); DoStuff (cat);
user3285954
2
Bez walki. Nie mam odczuć odnośnie do jakichkolwiek sposobów deklarowania zmiennych (ukrytych lub jawnych). Właściwie używam co najmniej jednego z większości dni. Podkreślam po prostu, że kiedy wybierzesz metodę niejawną (var), kompilator wybierze dla ciebie najwęższy możliwy typ. Co nie zawsze może być tym, czego chcesz. To wszystko.
xtrem,
2

Moim zdaniem varnależy go używać tylko wtedy, gdy jest natychmiast jasne, jaki jest typ przy definiowaniu wartości zmiennej.

Przykład:

var s = "string value";

Oczywiste jest, że sjest to string.

Uważam, że jest to również właściwe, gdy nazwa typu zmiennej jest bardzo złożona.

Przykład:

Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>> dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

// This is a little easier to read than the above statement
var dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

Poza tymi scenariuszami nie widzę żadnego ZYSKU do użycia przy użyciu var, ale mogę wymyślić kilka scenariuszy, w których może to być szkodliwe:

Na przykład typ jednorazowy, którego wartość zmiennej po prawej stronie nie pokazuje wyraźnie typu. Pozbywanie się urządzenia IDisposable można łatwo zapomnieć

Przykład:

// returns some file writer
var wr = GetWriter();

wr.add("stuff");
wr.add("more stuff");

//...
//...

// Now `wr` needs to be disposed, 
// but there is no clear indication of the type of `wr`,
// so it will be easily overlooked by code writer and code reviewer.
James Wierzba
źródło
1

„var” dodaje do kodu swego rodzaju „dynamiczny” element (chociaż kod pozostaje oczywiście ściśle wpisany). Odradzam używanie go w przypadkach, gdy typ nie jest jasny. Rozważ ten przykład:

var bar = GetTheObjectFromDatabase();
bar.DoSomething();

ClassA {
  void DoSomething() {
  //does something
  }
}

ClassB {
  void DoSomething() {
  //does something entirely different
  }
}

W przypadku zmiany zwracanego typu GetTheObjectFromDatabase () z Type A na B nie zauważymy, ponieważ obie klasy implementują DoSomething (). Jednak kod może teraz zrobić coś zupełnie innego.

Może to być tak subtelne, jak pisanie różnych rzeczy do dziennika, więc możesz nie zauważyć, że unitl jest już za późno.

Następujące użycie var powinno zawsze być w porządku:

var abc = new Something();
lolaldanee
źródło
1

Dla tych, którzy nie lubią ciągłego używania „var”, możesz także powstrzymać ReSharper przed domyślnym ustawieniem var podczas wykonywania „wprowadzenia zmiennej”. To było coś, co frustrowało mnie przez długi czas, zawsze domyślnie zmieniało się, a ja zmieniałem to za każdym razem.

Te ustawienia znajdują się w obszarze Edycja kodu> C #> Styl kodu

wprowadź opis zdjęcia tutaj

Derek
źródło
0

Nie ma różnicy technicznej (jak wskazał eWolf). Możesz użyć jednego lub drugiego, wygenerowany kod CLR będzie wyglądał tak samo.

Moim zdaniem główną zaletą jest to, że zmusza cię to do korzystania z lepszego nazewnictwa zmiennych. W twoim przykładzie „foo” jest dość kiepskim wyborem dla nazwy zmiennej.

Jaco Pretorius
źródło
0

Według JetBrains (autor ReSharper), domyślnie zachęcają do korzystania z var.

Z ich strony internetowej :

Stosowanie niejawnie wpisanych zmiennych lokalnych (znanych również jako varsłowo kluczowe) wprowadzone w C # 3.0 stało się dość popularne, ponieważ poprawia czytelność w wielu scenariuszach. Domyślnie ReSharper zachęca również do używania varsłowa kluczowego, ale preferencje jego użycia są elastycznie konfigurowalne - na przykład możesz zdecydować się na użycie jawnych typów w określonych przypadkach lub wszędzie, a ReSharper pomoże Ci egzekwować swoje preferencje.

Jeff Reddy
źródło
Gdzie mogę skonfigurować, kiedy wymagać jednoznacznej deklaracji typu?
user764754,