2015-07-21 9 views
7

Ho letto la sezione 2.3.2 del libro di Skeet e, dalla mia comprensione, non esiste un riferimento vero in C#, come in C++.Leggi il capitolo di Jon Skeet sui riferimenti rispetto ai valori. Ancora confuso

E 'interessante notare che non solo è il bit "per riferimento" della mito innacurate, ma così è il "oggetti vengono passati" bit. Gli oggetti sono non inviati mai passati, per riferimento o per valore. Quando è coinvolto un tipo di riferimento , la variabile viene passata per riferimento oppure il valore dell'argomento (il riferimento) viene passato per valore.

Sede, che è diverso da C++ (Io vengo da un background C++), perché in C++ è possibile utilizzare la e commerciale utilizzare direttamente un oggetto in un elenco di parametri - nessuna copia di nulla, nemmeno una copia del indirizzo di memoria dell'oggetto:

bool isEven (int & i) { return i % 2 == 0 }) 

int main() 
{ 
    int x = 5; 
    std::cout << isEven(x); // is the exact same as if I had written 
          // std::cout (x % 2 == 0) 
    return 0; 
} 

Non esiste un equivalente di quanto sopra. Il meglio che si può ottenere in C# è un equivalente di

bool isEven (int * i) { return *i % 2 == 0 }) 

int main() 
{ 
    int x = 5; 
    std::cout << isEven(&x); // is like 
          // int * temp = &x; 
          // return *temp % 2 == 0; 
          // (garbage collect temp) 
    return 0; 
} 

che passa nel valore di una sorta di riferimento (un puntatore) e, naturalmente, è inutile nel mio esempio, perché tutto ciò che è stata passata in un piccolo primitivo (int).

Da quello che ho capito, non esiste una sintassi C# che designi esplicitamente un elemento come riferimento, nessun equivalente dello & nel mio esempio C++. L'unico modo per sapere se hai a che fare con un valore o riferimento è memorizzare i tipi di elementi che sono riferimenti quando vengono copiati e quali tipi sono valori. È come JavaScript in questo senso.

Si prega di criticare la mia comprensione di questo concetto.

+1

Cosa c'è di sbagliato con il parametro 'ref'. modificatore? Inoltre, non penso che C++ funzioni nel modo in cui pensate di interpretare la spiegazione del primo snippet. Ciò che stai descrivendo è inlining. – leppie

+0

@leppie Immagino di non averlo ancora imparato. Ops. – user5124106

+0

@LarryPage "Memorizzare quali tipi di elementi sono riferimenti" in .NET è semplice, le classi sono "tipi di riferimento" e le strutture sono "tipi di valore". In un modo troppo semplificato, quando si passa una variabile che è un'istanza di una classe, si sta essenzialmente passando un riferimento a quell'istanza di una classe. Quando si passa una variabile che è un'istanza di una struct, si passa a una _copy_ di tale istanza. – jduncanator

risposta

7

In C#, tutte le classi sono tipi di riferimento e tutto il resto (credo) non lo è.

Esistono due diversi concetti qui:
tipi riferimento, dove un "riferimento" è un valoreche fa riferimento ad un esempio di classe, e
passaggio per riferimento, dove un "riferimento" è qualcosa che si riferisce a una variabile.

La parola "riferimento" indica cose leggermente diverse nei due contesti ed è importante tenerli separati.
IIRC, Skeet ha una buona spiegazione della differenza tra variabili, nomi, valori e diversi significati di "riferimento".

(Se si immagina una variabile come una casella in cui è possibile inserire oggetti e riferimenti come parti di una stringa, il primo "riferimento" è un pezzo di stringa legato a una cosa e il secondo "riferimento" è una stringa legata . ad una scatola)

(e dei parametri di riferimento C++ sono implementati passando l'indirizzo - è il modo più semplice ed efficace per riferirsi a qualcosa memorizzato altrove)

2

Se ho capito correttamente la tua domanda, è difficile che tu sappia che è un riferimento o un tipo di valore.

Il modo semplice di fare è sapere cosa stai usando una chiamata o una struttura.

Tutte le classi sono tipi di riferimento e tutte le struct sono tipi di valore. Anche int è struct

public struct Int32 

nello stesso modo in cui è anche bool

public struct Boolean 

Per conoscere i dettagli della classe è necessario premere 'F12' sulla parola chiave.

Problemi correlati