Domanda

Prendi il seguente frammento:

List<int> distances = new List<int>();

La ridondanza era intesa dai progettisti del linguaggio? In tal caso, perché?

È stato utile?

Soluzione

Il motivo per cui il codice sembra ridondante è perché, per un programmatore principiante, sembra che stia definendo la stessa cosa due volte. Ma questo non è ciò che sta facendo il codice. Sta definendo due cose separate che sono solo dello stesso tipo. Sta definendo quanto segue:

  1. Una variabile denominata distanze di tipo List<int>.
  2. Un oggetto nell'heap di tipo <=>.

Considera quanto segue:

Person[] coworkers = new Employee[20];

Qui la non ridondanza è più chiara, perché la variabile e l'oggetto allocato sono di due tipi diversi (una situazione che è legale se l'oggetto & # 8217; s deriva o implementa la variabile & # 8217; tipo s).

Altri suggerimenti

Cosa c'è di riduttivo in questo?

List<int> listOfInts = new List<int>():

Tradotto in inglese: (EDIT, ripulito un po 'per chiarimenti)

  • Crea un puntatore di tipo Elenco < int > e nominalo listofInts.
  • listOfInts è ora creato ma è solo un puntatore di riferimento che punta verso il nulla (null)
  • Ora, crea un oggetto di tipo Elenco < int > sull'heap e restituire il puntatore a listOfInts.
  • Ora listOfInts punta a un elenco < int > sul mucchio.

Non molto dettagliato quando pensi a quello che fa.

Ovviamente esiste un'alternativa:

var listOfInts = new List<int>();

Qui stiamo usando l'inferenza del tipo di C #, poiché ti stai assegnando immediatamente ad esso, C # può capire quale tipo vuoi creare dall'oggetto appena creato nell'heap.

Per comprendere appieno come il CLR gestisce i tipi, ti consiglio di leggere CLR Via C # .

Potresti sempre dire:

 var distances = new List<int>();

Come altri hanno già detto: var rimuove la ridondanza, ma ha potenziali conseguenze di manutenzione negative. Direi che ha anche potenziali conseguenze positive sulla manutenzione.

Fortunatamente Eric Lippert ne scrive molto più eloquentemente di me: http://csharpindepth.com/ViewNote.aspx?NoteID=63 http://csharpindepth.com/ViewNote.aspx?NoteID=61

Perché dichiarare un tipo non ha necessariamente nulla a che fare con l'inizializzazione.

Posso dichiarare

List<int> foo; 

e lasciarlo essere inizializzato in seguito. Dov'è la ridondanza allora? Forse riceve il valore da un'altra funzione come BuildList ().

Come altri hanno già detto, la nuova parola chiave var ti consente di aggirare il problema, ma devi inizializzare la variabile alla dichiarazione in modo che il compilatore possa dire di che tipo è.

invece di considerarlo ridondante, pensa a quel costrutto come una caratteristica che ti consente di salvare una linea.

invece di aver

Elenca le distanze; distanze = nuovo elenco ();

c # ti consente di metterli su una riga.

Una riga dice " Userò una variabile chiamata distanze , e sarà di tipo Elenco. " Un'altra riga dice & Quot; Assegna un nuovo elenco e chiama il costruttore senza parametri & Quot ;.

È troppo ridondante? Forse. farlo in questo modo ti dà alcune cose, però

1 . Separa la dichiarazione delle variabili dall'allocazione degli oggetti. Permettere:

IEnumerable<int> distances = new List<int>();
// or more likely...
IEnumerable<int> distances = GetList();

2. Consente un più forte controllo statico del tipo da parte del compilatore, fornendo errori del compilatore quando le dichiarazioni non corrispondono alle assegnazioni, piuttosto che errori di runtime.

Sono entrambi necessari per la scrittura del software? No. Esistono molte lingue che non lo fanno e / o differiscono su molti altri punti.

&

quot; Dottore! fa male quando lo faccio! " - " Non farlo più "

Se ritieni di non aver bisogno o desideri ciò che ti offre c #, prova altre lingue. Anche se non li usi, conoscerne altri può darti una spinta enorme nel modo in cui affronti i problemi. Se ne usi uno, fantastico!

Ad ogni modo, potresti trovare abbastanza prospettiva per permetterti di dire " Non ho bisogno del rigoroso controllo statico del tipo imposto dal compilatore c #. Userò python & Quot ;, piuttosto che flaming c # come troppo ridondante.

Potrebbe anche fare:

var distances = new List<int>();

I miglioramenti del compilatore per C # 3.0 (che corrisponde a .Net 3.5) eliminano alcune di queste cose. Quindi il tuo codice ora può essere scritto come:

var distances = new List<int>();

Il compilatore aggiornato è molto più bravo a capire i tipi in base a informazioni aggiuntive nell'istruzione. Ciò significa che ci sono meno casi in cui è necessario specificare un tipo per un compito o come parte di un generico.

Detto questo, ci sono ancora alcune aree che potrebbero essere migliorate. Alcuni di questi sono API e altri sono semplicemente dovuti alle restrizioni della digitazione forte.

La ridondanza non era di per sé intesa, ma era un effetto collaterale del fatto che tutte le variabili e tutti i campi dovevano avere una dichiarazione di tipo. Quando si tiene conto del fatto che tutte le istanze dell'oggetto menzionano anche il nome del tipo in un'espressione nuova , si ottengono dichiarazioni dall'aspetto ridondante.

Ora, con la deduzione del tipo mediante la parola chiave var , è possibile eliminare la ridondanza. Il compilatore è abbastanza intelligente da capirlo. Il prossimo C ++ ha anche una parola chiave auto che fa la stessa cosa.

Il motivo principale per cui sono stati introdotti var , tuttavia, è stato per i tipi anonimi, che non hanno un nome:

var x = new {Foo = Bar, Number = 1};

È solo " ridondante " se lo stai confrontando con lingue tipizzate dinamicamente. È utile per il polimorfismo e la ricerca di bug in fase di compilazione. Inoltre, semplifica il completamento automatico del codice / intellisense per il tuo IDE (se ne usi uno).

Un artefatto storico di tipizzazione statica / sintassi C; confronta l'esempio di Ruby:

distances = []

C # sta diventando decisamente meno dettagliato dopo l'aggiunta del supporto funzionale.

Usa var se è ovvio quale sia il tipo per il lettore.

//Use var here
var names = new List<string>();

//but not here
List<string> names = GetNames();

Da microsoft Guida alla programmazione C #

  

La parola chiave var può anche essere utile   quando il tipo specifico della variabile   è noioso digitare sulla tastiera, oppure   è ovvio o non si aggiunge a   leggibilità del codice

Il tuo esempio particolare è davvero un po 'prolisso, ma in molti modi C # è piuttosto snello.

Preferirei di gran lunga questo (C #)

int i;

a questo (VB.NET)

Dim i as Integer

Ora, l'esempio particolare che hai scelto è qualcosa su .NET in generale che è un po 'lungo, ma non penso che sia colpa di C #. Forse la domanda dovrebbe essere riformulata & Quot; Perché il codice .NET è così dettagliato? & Quot;

Vedo un altro problema con l'uso di var per pigrizia del genere

var names = new List<string>();

Se si utilizza var, la variabile denominata " names " è digitato come List<string>, ma alla fine useresti solo una delle interfacce ereditate da List<T>.

IList<string> = new List<string>();
ICollection<string> = new List<string>();
IEnumerable<string> = new List<string>();

Puoi usare automaticamente tutto ciò, ma puoi considerare quale interfaccia vuoi usare al momento in cui hai scritto il codice?

La parola chiave var non migliora la leggibilità in questo esempio.

In molte delle risposte a questa domanda, gli autori pensano come compilatori o apologeti. Una regola importante per una buona programmazione è Non ripeterti!

Evitare questa ripetizione non necessaria è un obiettivo di progettazione esplicito di Go, ad esempio:

  

La balbuzie (foo.Foo* myFoo = new(foo.Foo)) è ridotta dalla semplice derivazione del tipo usando il costrutto := declare-e-inizializza.

Perché siamo dipendenti da compilatori ed errori del compilatore.

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