Domanda

Ho capito che se mi passa un valore di tipo (int, struct, etc.) come parametro (senza la parola chiave ref), una copia di tale variabile viene passata al metodo, ma se uso la parola ref un viene passato riferimento a quella variabile, non è uno nuovo.

Ma con riferimento-tipi, come le classi, anche senza la parola chiave ref, viene passato un riferimento al metodo, non una copia. Allora, qual è l'uso della parola chiave ref con riferimento tipi?


Prendiamo ad esempio:

var x = new Foo();

Qual è la differenza tra i seguenti?

void Bar(Foo y) {
    y.Name = "2";
}

e

void Bar(ref Foo y) {
    y.Name = "2";
}
È stato utile?

Soluzione

È possibile modificare ciò foo punti da utilizzare y:

Foo foo = new Foo("1");

void Bar(ref Foo y)
{
    y = new Foo("2");
}

Bar(ref foo);
// foo.Name == "2"

Altri suggerimenti

Ci sono casi in cui si desidera modificare l'attuale di riferimento e non l'oggetto puntato:

void Swap<T>(ref T x, ref T y) {
    T t = x;
    x = y;
    y = t;
}

var test = new[] { "0", "1" };
Swap(ref test[0], ref test[1]);

un grande articolo su parametro che passa in C #. Dettaglia chiaramente il comportamento e l'utilizzo di passaggio di parametri per valore, per riferimento (ref) esatto, e dall'uscita (out).

Ecco un preventivo importante da quella pagina in relazione ai parametri ref:

  

Parametri di riferimento non passano il   valori delle variabili utilizzate nella   membro invocazione funzione - usano   le variabili stesse. Piuttosto che   creazione di un nuovo percorso di archiviazione per   la variabile nel membro funzione   dichiarazione, la stessa posizione di memorizzazione   viene utilizzato, in modo che il valore della variabile   nel membro funzione e il valore   del parametro di riferimento sarà sempre   essere lo stesso. Parametri di riferimento hanno bisogno   l'arbitro modificatore come parte sia   dichiarazione e l'invocazione - che   significa che è sempre chiaro quando sei   passando qualcosa per riferimento.

Molto ben spiegato qui: http://msdn.microsoft.com/en-us/library/s6938f28.aspx

Estratto dall'articolo:

  

Una variabile di un tipo di riferimento non contiene direttamente i suoi dati; esso   contiene un riferimento ai suoi dati. Quando si passa un riferimento di tipo   parametro per valore, è possibile modificare i dati a cui punta   il riferimento, ad esempio il valore di un membro della classe. Tuttavia, è   non può modificare il valore del riferimento stesso; che è, non si può   utilizzare lo stesso riferimento allocare memoria per una nuova classe e falla   persistere all'esterno del blocco. Per fare questo, passare il parametro utilizzando il   ref o parola chiave fuori.

Quando si passa un tipo di riferimento con la parola chiave ref, si passa il riferimento per riferimento, e il metodo si chiama possibile assegnare un nuovo valore al parametro. Questo cambiamento si propaga al campo di applicazione chiamando. Senza ref, il riferimento è passato per valore, e questo non accade.

C # ha anche la parola 'out', che è un po 'come ref, se non che con 'ref', gli argomenti devono essere inizializzati prima di chiamare il metodo, e con la 'fuori' è necessario assegnare un valore nel metodo di ricezione.

Permette di modificare il riferimento passato in. Es.

void Bar()
{
    var y = new Foo();
    Baz(ref y);
}

void Baz(ref Foo y)
{
    y.Name = "2";

    // Overwrite the reference
    y = new Foo();
}

È inoltre possibile utilizzare se non si preoccupano il riferimento passato in:

void Bar()
{
    var y = new Foo();
    Baz(out y);
}

void Baz(out Foo y)
{
    // Return a new reference
    y = new Foo();
}

Un altro mucchio di codice

class O
{
    public int prop = 0;
}

class Program
{
    static void Main(string[] args)
    {
        O o1 = new O();
        o1.prop = 1;

        O o2 = new O();
        o2.prop = 2;

        o1modifier(o1);
        o2modifier(ref o2);

        Console.WriteLine("1 : " + o1.prop.ToString());
        Console.WriteLine("2 : " + o2.prop.ToString());
        Console.ReadLine();
    }

    static void o1modifier(O o)
    {
        o = new O();
        o.prop = 3;
    }

    static void o2modifier(ref O o)
    {
        o = new O();
        o.prop = 4;
    }
}

In aggiunta alle risposte esistenti:

Per quanto hai chiesto per la differenza dei 2 metodi: Non c'è co (Ntra) varianza quando si utilizza ref o out:

class Foo { }
class FooBar : Foo { }

static void Bar(Foo foo) { }
static void Bar(ref Foo foo) { foo = new Foo(); }

void Main()
{
    Foo foo = null;
    Bar(foo);           // OK
    Bar(ref foo);       // OK

    FooBar fooBar = null;
    Bar(fooBar);        // OK (covariance)
    Bar(ref fooBar);    // compile time error
}

Un parametro in un metodo sembra essere sempre passare una copia, la domanda è una copia di quello. Una copia è fatto da un costruttore di copia per un oggetto e dal momento che tutte le variabili sono oggetto in C #, credo che questo sia il caso per tutti loro. Variabili (oggetti) sono come le persone che vivono in alcuni indirizzi. O ci cambiamo le persone che vivono in quegli indirizzi o possiamo creare più riferimenti alle persone che vivono in quegli indirizzi in rubrica (fare copie poco profonde). Così, più di un identificatore può fare riferimento allo stesso indirizzo. I tipi di riferimento desiderare di più spazio, quindi a differenza di tipi di valore che sono direttamente collegati da una freccia alla loro identificazione nella pila, che hanno valore per un altro indirizzo nel mucchio (uno spazio più grande di abitare). Questo spazio deve essere presa dal mucchio.

Tipo di valore: Identificatore (contiene value = indirizzo del valore di pila) ----> Valore del tipo di valore

Tipo di riferimento: Identifier (contiene value = indirizzo del valore pila) ----> (contiene value = indirizzo del valore mucchio) ----> valore Heap (più spesso contiene indirizzi ad altri valori), immaginate più frecce attaccare in diverse direzioni per Array [0], Array [1], matrice [2]

L'unico modo per modificare un valore deve seguire le frecce. Se una freccia si perde / modificato nel modo in cui il valore non è raggiungibile.

variabili di riferimento portano l'indirizzo da un luogo all'altro in modo che qualsiasi updation su di loro in qualsiasi luogo rifletterà su tutti i luoghi allora che cosa è l'uso di REF. variabile di riferimento (405) sono buoni finché non nuova memoria viene allocata alla variabile di riferimento passata nel metodo.

Una volta che la nuova memoria allocare (410) allora la variazione del valore su questo oggetto (408) non rifletterà in tutto il mondo. Per questo riferimento viene. Ref è riferimento di riferimento così ogni volta nuova memoria allocare che arrivare a conoscere perché punta a quella posizione quindi il valore può essere condiviso da tutti. Potete vedere l'immagine per più clearity.

Ref in riferimento variabile

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