Domanda

    

Questa domanda ha già una risposta qui:

    
            
  •              Uso della parola chiave var in C #                                      86 risposte                          
  •     
    

questa è una domanda che durante la programmazione mi chiedo sempre: cosa usare quando scriviamo il codice:

var myFiles = Directory.GetFiles(fullPath);

o

string[] myFiles = Directory.GetFiles(fullPath);

var è nuovo ed è un Variabili locali tipizzate in modo implicito , quindi possiamo usare solo localmente e ha regole che non possono essere null, ecc., ma mi chiedo se traiamo vantaggio dall'usarlo " normalmente " ;.

Il " normalmente " dice la parte, non in Tipi anonimi , inizializzatori di oggetti e raccolte e espressioni di query dove si intendeva usare l'oggetto anonimo var, quindi cosa Voglio dire è ... proprio come nell'esempio sopra.

quali sono i tuoi pensieri?

È stato utile?

Soluzione

Oltre all'uso ovvio di var con LINQ, lo uso anche per abbreviare le dichiarazioni di variabili pelose per leggibilità, ad es .:

var d = new Dictionary<string, Dictionary<string, Queue<SomeClass>>>();

In generale, ottengo una sorta di conforto (per mancanza di una parola migliore) dalla digitazione statica che mi rende riluttante a rinunciarvi. Mi piace la sensazione di sapere cosa sto facendo quando dichiaro una variabile. Dichiarare una variabile non è solo dire qualcosa al compilatore, ma dire alla persona che legge qualcosa nel tuo codice.

Lascia che ti faccia un esempio. Supponiamo di avere un metodo che restituisce un List<string>. Questo codice è certamente corretto, e penso che sia come il 90% degli sviluppatori C # probabilmente lo scriverebbe:

List<string> list = MyMethod();

Ovviamente, vero? In effetti, ecco un posto in cui puoi usare facilmente rows.

Abbastanza vero. Ma questa versione del codice non sta semplicemente dichiarando una variabile, ma mi sta dicendo cosa intende fare la persona che l'ha scritto:

IEnumerable<string> list = MyMethod();

Lo sviluppatore che ha scritto quel codice mi sta dicendo " Non cambierò questo elenco, né userò un indice per accedere ai suoi membri. Tutto ciò che farò è iterare attraverso di esso. & Quot; Sono molte le informazioni da comunicare in un'unica riga di codice. È qualcosa che ti arrendi se usi IEnumerable<DataRow>.

Ovviamente, non ti arrendi se non lo stavi usando in primo luogo. Se sei il tipo di sviluppatore che scriverebbe quella riga di codice, sai già che non useresti IEnumerable<T> lì.

Modifica:

Ho appena riletto il post di Jon Skeet e questa citazione di Eric Lippert è saltata fuori da me:

  

I locali tipizzati in modo implicito sono solo un piccolo modo in cui puoi de-enfatizzare il come e quindi sottolineare il cosa.

Penso che in realtà in molti casi l'uso della tipizzazione implicita stia lasciando ciò che è implicito. Va bene non soffermarsi sul cosa. Ad esempio, scriverò casualmente una query LINQ come:

var rows = from DataRow r in parentRow.GetChildRows(myRelation)
           where r.Field<bool>("Flag")
           orderby r.Field<int>("SortKey")
           select r;

Quando leggo quel codice, una delle cose che penso quando lo leggo è " <=> è un <=>. " Perché so che le query LINQ restituite sono <=> e posso vedere il tipo di oggetto selezionato proprio lì.

Questo è un caso in cui ciò che non è stato reso esplicito. Mi è rimasto da dedurre.

Ora, in circa il 90% dei casi in cui utilizzo LINQ, questo non ha importanza. Perché il 90% delle volte, la riga di codice successiva è:

foreach (DataRow r in rows)

Ma non è difficile immaginare il codice in cui sarebbe molto utile dichiarare <=> come <=> - codice in cui venivano interrogati molti tipi diversi di oggetti, non era possibile inserire la dichiarazione della query accanto all'iterazione e sarebbe utile poter ispezionare <=> con IntelliSense. Ed è una cosa, non una cosa.

Altri suggerimenti

Otterrai una grande varietà di opinioni su questo - da " usa var ovunque " a " usa solo var con tipi anonimi, dove in pratica devi. " Mi piace Il punto di vista di Eric Lippert :

  

Tutto il codice è un'astrazione. È cosa   il codice è & # 8220; in realtà & # 8221; fare è   manipolazione dei dati? No. numeri? Bit?   No. Tensioni? No. Elettroni? Si ma   comprendere il codice a livello di   gli elettroni è una cattiva idea! L'arte di   la programmazione è capire quale sia il diritto   il livello di astrazione è per   pubblico.

     

In una lingua di alto livello c'è   sempre questa tensione tra COSA il   codice fa (semanticamente) e COME il   il codice lo compie. Manutenzione   i programmatori devono capire entrambi   il cosa e il come se & # 8217; stanno andando   avere successo nel fare cambiamenti.

     

L'intero punto di LINQ è che   de-enfatizza in modo massiccio il " come " e   enfatizza in modo massiccio il " what " ;. Di   usando una comprensione di query, il   il programmatore sta dicendo al futuro   pubblico " Credo che dovresti   né sapere né preoccuparsi esattamente di come questo   il set di risultati è in fase di calcolo, ma tu   dovrebbe preoccuparsi molto di ciò che il   la semantica dell'insieme risultante è. "   Rendono il codice più vicino al   processo aziendale in corso di attuazione e   più lontano dai bit e dagli elettroni   che lo fanno andare.

     

I locali tipizzati in modo implicito sono solo uno   piccolo modo in cui è possibile delimitare   il come e quindi enfatizzare il   che cosa. Se questa è la cosa giusta   fare in un caso particolare è un   giudizio. Quindi lo dico alla gente   se la conoscenza del tipo è pertinente   e la sua scelta è cruciale per il   proseguimento del metodo,   quindi non utilizzare la digitazione implicita.   La digitazione esplicita dice & Quot; te lo sto dicendo   come funziona per un motivo, paga   attenzione " ;. La digitazione implicita dice & Quot; it   & # 8217; non importa un po 'se questo   cosa è un elenco o un   Cliente [], ciò che conta è che lo sia   una raccolta di clienti. "

Personalmente non tendo di usarlo se il tipo non è ragionevolmente ovvio - dove includo le query LINQ come " ragionevolmente ovvio " ;. Non lo farei per Directory.GetFiles per esempio, dato che non è davvero ovvio che restituisce un string[] invece di (diciamo) un FileInfo[] (o qualcos'altro del tutto) - e questo fa una grande differenza per quello che fare più tardi.

Se c'è una chiamata del costruttore sul lato destro dell'operatore di assegnazione, sono molto più probabile che vada con var: è palesemente ovvio quale sarà il tipo. Ciò è particolarmente utile con tipi generici complessi, ad es. Dictionary<string,List<int>>.

Personalmente uso var in due posti:

  1. Con tipi anonimi, ad es. Relativo a LINQ (dove var è richiesto in alcuni casi)
  2. Quando l'istruzione dichiara e costruisce un tipo specifico nello stesso tipo

es. questo è un esempio del punto 2:

var names = new List<String>();

Modificato : questo in risposta alla domanda di Jon Skeet.

La risposta sopra è stata infatti semplificata. Fondamentalmente, uso var dove il tipo è:

  1. Inutile sapere (non che molti posti però)
  2. Impossibile sapere (LINQ, tipi anonimi)
  3. Altrimenti noto o cancellato dal codice

Nel caso di un metodo factory, dove tutto ciò che devi sapere nel punto in cui scrivi il codice è che l'oggetto che ricevi è un discendente di qualche tipo e che un tipo ha un metodo factory statico, quindi userei var . In questo modo:

var connection = DatabaseConnection.CreateFromConnectionString("...");

L'esempio sopra è un vero esempio dal mio codice. È chiaro, almeno per me e per le persone che usano questo codice, che connessione è un discendente DatabaseConnection, ma il tipo esatto non è necessario né per comprendere il codice né utilizzarlo.

Ho provato il " usa var ovunque " stile ... ed ecco perché non ho continuato a usarlo.

  1. Leggibilità degradata a volte
  2. Limita Intellisense dopo =
  3. Digitando " var " in realtà non era molto più breve della digitazione di " int " ;, " string " ;, ecc., specialmente con intellisense.

Detto questo, lo uso ancora con LINQ.

Proveniente dalla terra della programmazione funzionale, dove l'inferenza del tipo domina il giorno, uso var per tutti i locali dove possibile.

In Visual Studio, se ti stai mai chiedendo quale sia il tipo di qualsiasi locale, tutto ciò che devi fare è passarci sopra con il mouse.

Questo post ha alcune buone linee guida su quando usare l'interfaccia di tipo var o tipi di oggetto.

Tendo a usare var ovunque, ma i miei colleghi hanno detto basta, è meno leggibile per noi. Quindi ora uso <=> solo su tipi anonimi, query LINQ e dove si trova il costruttore sul lato destro.

Penso che sia interessante notare come questo di solito viene gestito in Haskell. Grazie al isomorfismo di Curry-Howard , il tipo (più generale) di qualsiasi espressione in Haskell può essere dedotto, e quindi le dichiarazioni di tipo non sono essenzialmente richieste da nessuna parte, con poche eccezioni; ad esempio, a volte vuoi deliberatamente limitare il tipo a qualcosa di più specifico di quanto si supponga.

Naturalmente, ciò che è richiesto e ciò che è raccomandato non sono la stessa cosa; in pratica, la convenzione sembra essere che le definizioni di livello superiore abbiano sempre dichiarazioni di tipo, mentre le definizioni localizzate hanno lasciato le dichiarazioni di tipo. Questo sembra trovare un buon equilibrio tra esplicito per la leggibilità della definizione nel suo insieme, in contrasto con la brevità per la leggibilità del & Quot locale; helper & Quot; oppure " temporaneo " definizioni. Se ho capito bene, non puoi usare var per & Quot; top-level & Quot; definizioni (come un metodo o una funzione globale) in primo luogo, quindi suppongo che ciò si traduca in " usa int ovunque puoi " nel mondo C #. Naturalmente, digitando & Quot; <=> & Quot; è lo stesso numero di sequenze di tasti di " <=> " ;, ma la maggior parte degli esempi sarà più lunga di quella.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top