Riferimenti didattici in C #
-
22-07-2019 - |
Domanda
Tra un paio di settimane, insegnerò a una classe di ingegneri del primo anno i punti salienti dei riferimenti in C # come parte del loro corso di programmazione del primo anno. Molti di loro non hanno mai programmato prima, e hanno avuto abbastanza problemi nell'apprendimento degli oggetti, quindi insegnare i riferimenti sarà una battaglia in salita. Ho in programma di avere molti esempi disponibili per gli studenti da esaminare da soli, ma solo mostrare un mucchio di esempi tende a essere piuttosto travolgente se il concetto sottostante non "fa clic".
Quindi porterò la domanda alla comunità SO: qual è il modo migliore in cui hai visto insegnare i riferimenti? Cosa l'ha reso 'clic' per te? C'è qualche materiale di riferimento che mi manca?
Il mio programma di lezioni provvisorie è:
- Che cos'è un riferimento (utilizzando un argomento come quello di Eric Lippert )
- Riferimenti e Garbage Collector
- Tipi di riferimento e tipi di valore
- Tipi immutabili
- Passaggio per riferimento rispetto a Passaggio per valore (e tutte le sottigliezze dei riferimenti agli oggetti passati per valore)
- Una manciata di esempi cattivi che producono risultati inaspettati se non capisci 1-5.
Soluzione
Un modo in cui l'ho sentito spiegare è usare un cellulare o un walkie-talkie. Tu (l'istruttore) hai un'estremità e dichiari di essere un'istanza di oggetto. Rimani in un posto (es. Il mucchio) mentre gli studenti passano dall'altra parte (che è in vivavoce se si tratta di un telefono cellulare) intorno alla classe.
Possono interagire con te attraverso il " riferimento " hanno te, ma in realtà non hanno " tu " in loro possesso.
Altri suggerimenti
Mi piace l'analogia dell'URL che descrive le differenze tra i tipi di riferimento e di valore. È possibile passare un URL come riferimento ad alcuni contenuti. Puoi modificare quell'URL senza modificare quel contenuto. Puoi anche accedere al contenuto tramite l'URL per modificare il contenuto.
Questo è un riferimento utile:
http://www.yoda.arachsys.com/csharp/parameters.html
Prova a spiegare i riferimenti con figure , poiché il testo puro a volte non riesce a raggiungere la maggior parte delle persone. Molte risorse e libri sull'argomento, provano a spiegare attraverso cifre in quanto è difficile correlare l'allocazione attraverso la sola comunicazione verbale (questo è principalmente un problema di attenzione per la maggior parte delle persone).
Almeno prova a sottolineare come gli oggetti si relazionano tra loro, un semplice esempio sarebbe un semplice riferimento.
Data:
class A {
B b = new B();
}
class B {
int mine = 1;
}
Quando si crea un'istanza della classe A
come oggetto a
da un determinato contesto, la figura seguente illustrerà come apparirà tutto nell'heap. Il punto dell'illustrazione è mostrare come i diversi oggetti si relazionano tra loro e abbiano un modello mentale per come funziona l'heap.
+-A-----+
a: *---->| |
| | +-B--------+
| b: *--+-->| |
| | | mine: 1 |
+-------+ | |
+----------+
Prova anche a spiegare la differenza tra allocazione di heap e stack. Chiamare un metodo con parametri. Un semplice esempio potrebbe essere qualcosa del genere:
Dato il seguente metodo:
public void doSomething(B b) {
int doMine = b.mine + 1;
}
Quando si chiama doSomething
e si lascia fare le cose, alla fine lo stack di doSomething
sarà simile al seguente. Il punto che mostra che gli oggetti non risiedono direttamente all'interno di uno stack, ma è solo riferito a un oggetto nell'heap e gli oggetti sono condivisi tramite riferimenti.
whoever called doSomething *
|
v
+-doSomething-+ +-B--------+
| b: *--------+-->| |
|-------------| | mine: 1 |
| doMine: 2 | +----------+
+-------------+
Un altro esempio illustrativo sarebbe illustrare un array che è un oggetto e un array multidimensionale contiene un array di array.
Ho trovato questo articolo davvero utile per spiegando il parametro passando in C #. L'articolo fa anche un buon lavoro spiegando valore e tipi di riferimento in termini generali.
È più una rappresentazione visiva che mi ha aiutato molto.
Immagini e diagrammi.
Le persone formano immagini mentali dei concetti che stanno imparando e una rappresentazione visiva di riferimenti e la loro relazione con gli oggetti associati è un buon modo per iniziare. Allo stesso modo, visualizzare oggetto come contenente le variabili dei membri (che include riferimenti ad altri oggetti) e i metodi dei membri, come i diagrammi UML, è molto utile.
Successivamente, puoi approfondire i dettagli su come i riferimenti e i tipi primitivi sono effettivamente implementati, se senti la necessità di farlo. Ma ritarda queste discussioni il più a lungo possibile, poiché le persone possono impantanarsi nel tentativo di accoppiare concetti astratti ai dettagli rappresentativi, che distrae dall'apprendimento dei concetti astratti.
Quando stavo imparando VB6, i riferimenti in realtà mi confondevano un po '. Poi ho provato ad imparare il C ++ e, dopo aver trattato i puntatori, i riferimenti avevano perfettamente senso per me. Capirlo da una prospettiva di ciò che sta realmente accadendo è stato più facile per me che capirlo da una prospettiva di oo-concetti. Forse puoi approfondire le cose nascoste nella tua lezione.
Suggerirei di ridurre al minimo l'uso del termine "riferimento" nel complesso, poiché può essere utilizzato in .net per fare riferimento a due cose molto diverse: il contenuto delle posizioni di archiviazione di tipo classe e i parametri passati con un "ref" qualificatore. Usa il termine "riferimento oggetto" per il primo e "parametro di riferimento" per quest'ultimo.
Nel descrivere ciò che un "oggetto riferimento" " è, suggerirei di usare il termine "ID oggetto". Gli ID oggetto hanno alcune cose che li rendono diversi da " indirizzi " ;:
- Non si possono fare molte cose con gli ID oggetto. Si può verificare se uno è vuoto, verificare se due di essi sono uguali, copiarne uno in una posizione di archiviazione di tipo adatto o cercare l'oggetto a cui fa riferimento uno e chiedergli di fare qualcosa. La maggior parte delle richieste di fare qualcosa con un valore o una variabile di tipo classe sono in realtà richieste di fare qualcosa con l'oggetto a cui si fa riferimento. Si noti che non è possibile manipolare un ID di un oggetto in modo tale da ottenere l'ID di un altro, come si può fare con gli indirizzi.
- Sebbene il sistema debba disporre di un mezzo per convertire gli ID oggetto in indirizzi, non vi è alcuna garanzia che utilizzerà qualsiasi mezzo particolare per farlo. Né vi è alcuna garanzia che il modello di bit associato a qualsiasi ID oggetto non cambi spontaneamente; tutto ciò che è garantito è che se il modello di bit cambia, il nuovo modello farà riferimento allo stesso oggetto del vecchio.
- Il sistema tiene traccia di tutti i luoghi in cui sono memorizzati gli ID oggetto. Finché esiste una copia di un ID oggetto, tale ID oggetto non farà mai riferimento a nient'altro che all'istanza dell'oggetto per cui è stato creato. Al contrario, in generale, i sistemi che usano indirizzi per cose non tracciano ogni singolo posto in cui un indirizzo potrebbe essere copiato. È possibile che un oggetto cessi di esistere mentre qualcuno ha ancora una copia del suo indirizzo e alcuni nuovi oggetti potrebbero essere creati con lo stesso indirizzo.