Jawne definiowanie zmiennych typów danych a użycie słowa kluczowego „var”? [Zamknięte]

35

Czy w C # zachęca mnie do używania słowa kluczowego var uniwersalnego dla każdej deklaracji zmiennej? Jeśli tak, to czy muszę podać te znaki specjalne dla wartości literalnych w deklaracji zmiennej, takie jak M dla dziesiętnej, w następującej instrukcji:

var myDecimal = 14.5M;

Jeśli to robi różnicę, staram się zrobić programowanie w języku C #.

wassimans
źródło
7
Ma kilkanaście duplikatów w SO (gdzie należy do IMHO).
1
Te same pytania nadchodzą do C ++ z ponownym przeznaczeniem C ++ 0x auto.
David Thornley,
5
Eric Lippert z zespołu kompilatora C # niedawno napisał
Tim Goodman
Istnieje sześć miliardów duplikatów tego pytania.
DeadMG,
@DeadMG, który sprawia, że ​​jest ich sześć miliardów i jeden.
wassimans,

Odpowiedzi:

53

Było wiele sporów dotyczących korzystania z var. Moje ogólne zasady są następujące.

  • Gdy typ jest oczywisty, na przykład gdy prawa ręka przypisania jest konstruktorem, użyj var.
  • Gdy typ jest złożony do napisania, na przykład zapytanie LINQ (powód var w pierwszej kolejności), użyj var.
  • W przypadku typów ambiwalentnych (przykład dziesiętny), w których chcesz się upewnić, że zmienna jest poprawnie wpisana, przeliteruj ją.
  • Anonimowe typy muszą używać var.
  • We wszystkich innych przypadkach określ typ.

Zasadniczo celem jest ułatwienie odczytu kodu. Jeśli uważasz, że var wystarczy, ponieważ przypisanie jest oczywiste, użyj var. Użyj pełnej nazwy typu jako wskazówki dla czytelnika, jeśli uważasz, że jest to konieczne.

Michael Brown
źródło
9
Używam również „var” w foreachinstrukcjach, w których zależy mi tylko na wyliczeniu kolekcji, niekoniecznie na rodzaju każdego elementu.
Adam Lear
1
I jak wskazał Jesse anonimowe typy;)
Michael Brown
4
@AnnaLear czasem trzeba się jednak przejmować. foreach (var wiersz w datatable.Rows) w tym przypadku var jest obiektem, a nie DataRow, jak można by się spodziewać.
Thanos Papathanasiou
@ThanosPapathanasiou Pewnie, tak. To samo dotyczy kolekcji formantów w formularzach Windows Forms i prawdopodobnie także w innych sytuacjach.
Adam Lear
Zwykle używam var, z wyjątkiem sytuacji, gdy chcę się upewnić, jaki jest typ mojej zmiennej (na przykład gdy chcę mieć pewność, że wartość jest podwójna)
eka808,
14

Kiedy stosować varprogramowanie „świętej wojny”. Jest dokładnie jedno miejsce, w którym jest to wymagane: gdy wynik operacji tworzy anonimowy typ, taki jak:

var result = new { Name = "John", Age = 35 };

Gdziekolwiek indziej jest to opcjonalne i naprawdę zależy od twojego standardu kodowania, aby użyć go lub nie w innych sytuacjach.

I tak, będziesz potrzebował znaków specjalnych do literałów, aby poinformować kompilator, co znajduje się po prawej stronie. W przykładzie, bez M, domyślnie jest doublezamiast decimal.

Jesse C. Slicer
źródło
1
zapomniałem o anonimowych typach!
Michael Brown
W mojej ostatniej pracy powiedziano mi, że zostanę zwolniony, jeśli nadal będę używać słowa kluczowego „var” ...
hanzolo 18.09.13
To ekstremalne, ale inicjatywa twojej firmy. Cieszę się, że to twoja „ostatnia” praca! :)
Jesse C. Slicer
7

Z MSDN :

Jednak użycie var może przynajmniej utrudniać zrozumienie kodu dla innych programistów. Z tego powodu dokumentacja w języku C # zwykle używa var tylko wtedy, gdy jest to wymagane.

Naprawdę, naprawdę nie lubię niejawnego pisania. Na powierzchni sprawia, że ​​kod jest bardziej czytelny, ale może prowadzić do wielu problemów w przyszłości. Jeśli dev zmieni inicjalizator zmiennej, powiedzmy, z

var myFloat=100f;

do

var myFloat=100;

lub

var myFloat=100.0;

Typ ulegnie zmianie, co spowoduje całą masę błędów kompilatora lub, jeśli jest to widok internetowy i nie używasz kroku po kompilacji do wstępnej kompilacji swoich widoków, cała masa błędów środowiska wykonawczego, które nie zostaną wychwycone bez skutecznego testy przedwdrożeniowe.

Wpisywanie niejawne również nie działa wszędzie (z tego samego łącza MSDN)

Zmienna może być używana tylko wtedy, gdy zmienna lokalna jest zadeklarowana i zainicjowana w tej samej instrukcji; zmiennej nie można zainicjować na wartość null ani na grupę metod lub funkcję anonimową.

Zmienna nie może być używana w polach w zakresie klasy.

Zmienne zadeklarowane przy użyciu var nie mogą być użyte w wyrażeniu inicjalizacji. Innymi słowy, to wyrażenie jest zgodne z prawem: int i = (i = 20); ale to wyrażenie powoduje błąd czasu kompilacji: var i = (i = 20);

W tej samej instrukcji nie można zainicjować wielu zmiennych o niejawnym typie.

Jeśli typ o nazwie var znajduje się w zakresie, słowo kluczowe var rozpozna nazwę tego typu i nie będzie traktowane jako część niejawnie wpisanej deklaracji zmiennej lokalnej.

Utrzymywanie spójnego kodu (w tym przypadku używanie jawnego pisania wszędzie) jest bardzo, bardzo dobrą rzeczą. Moim zdaniem varjest leniwy i nie przynosi rzeczywistych korzyści, a także wprowadza kolejny potencjalny punkt awarii w już złożonym procesie.

Aktualizacja 2017

Całkowicie zmieniłem zdanie. Pracując w C #, używam varwiększość czasu (z wyjątkiem rzeczy takich jak zmienne typu interfejs i tym podobne). Zachowuje zwięzły kod, który poprawia czytelność. Mimo to - zwróć uwagę na to, czym tak naprawdę jest typ rozwiązany.

3Dave
źródło
Zastanawiasz się, co zmieniło twoje zdanie, @ 3Dave. Nadal w 100% zgadzam się z twoją pierwotną tezą: „var jest leniwy i nie przynosi rzeczywistych korzyści, i wprowadza kolejny potencjalny punkt awarii w już złożonym procesie”.
Dan
@ Dan To naprawdę sprowadza się do czytelności. Kompetentny programista może dość szybko ustalić, co jest po stronie inicjalizacji deklaracji bez problemu. Podobnie jak nie używanie this.wszędzie lub mówienie System.Blah.SomeTypezamiast using, co wciąż wydaje mi się niezwykle denerwujące, bardziej zwięzły kod jest - przynajmniej dla mnie - zazwyczaj łatwiejszy do analizy wizualnej. Nadal istnieje wiele scenariuszy, w których wyraźne wpisywanie jest właściwym wyborem. Ale w dzisiejszych czasach jestem mniej prawnikiem od języków niż ktoś, kto tylko próbuje uzyskać czysty kod za drzwiami.
3Dave
@Dan (Oczywiście, jestem również facetem, który używa using namespace std;plików .cpp. (Nie nagłówki, ponieważ wolałbym unikać smołowania i
upierzania
3

Odwołanie do C # pokazuje, co ilustruje dobre lub złe użycie tego konstruktu:

Poniższy przykład pokazuje dwa wyrażenia zapytania. W pierwszym wyrażeniu użycie var jest dozwolone, ale nie jest wymagane, ponieważ typ wyniku zapytania można jawnie podać jako IEnumerable. Jednak w drugim wyrażeniu należy użyć var, ponieważ wynik jest zbiorem anonimowych typów, a nazwa tego typu jest niedostępna z wyjątkiem samego kompilatora. Zauważ, że w przykładzie 2 element zmiennej iteracji foreach również musi być niejawnie wpisany.

 // Example #1: var is optional because 
    // the select clause specifies a string 
    string[] words = { "apple", "strawberry", "grape", "peach", "banana" };
    var wordQuery = from word in words
                    where word[0] == 'g'
                    select word;

    // Because each element in the sequence is a string,  
    // not an anonymous type, var is optional here also. 
    foreach (string s in wordQuery)
    {
        Console.WriteLine(s);
    }

    // Example #2: var is required because 
    // the select clause specifies an anonymous type 
    var custQuery = from cust in customers
                    where cust.City == "Phoenix" 
                    select new { cust.Name, cust.Phone };

    // var must be used because each item  
    // in the sequence is an anonymous type 
    foreach (var item in custQuery)
    {
        Console.WriteLine("Name={0}, Phone={1}", item.Name, item.Phone);
    }
Thulani Chivandikwa
źródło
0

Słowo kluczowe var wymaga tylko od kompilatora, aby automatycznie wydedukował typ zmiennej typu var. Dlatego jeśli chcesz przechowywać zmienną dziesiętną w zmiennej var, musisz użyć m. Podobnie, jeśli przechowujesz ciąg, musisz zawrzeć go w cudzysłowie.

Programista komputerowy
źródło
0

Dla mnie nie używam var w następujących przypadkach:

  • Kiedy chcę być pewien typu mojej zmiennej (na przykład, aby upewnić się, że użyty typ jest podwójny, a nie dziesiętny, a to wielka sprawa, zaufaj mi!)
  • Kod polimorficzny jak Fruit foo = new Apple();. W tym przypadku uważam, że var polega na unikaniu i korzystaniu z klasy nadrzędnej (tutaj Fruit) jest lepsze, umożliwiając lepsze zrozumienie logiki kodu i ograniczenie prawdopodobnych błędów (przy var, bez sprawdzania koncepcji polimorficznej!)

Co do reszty, myślę, że zależy to od przypadku i pochodzenia dewelopera. Niektórzy ludzie ze świata PHP wolą nie dbać o typy zmiennych, a niektórzy ludzie ze świata Java będą myśleć, że var jest herezją, a im bardziej gadatliwa, tym lepiej.

Będziesz musiał dokonać osobistej opinii :)

eka808
źródło