MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Variabile de tip referință și returnarea unei referințe

Pe lângă parametrii metodei, care cu ajutorul modificatorului ref permit transmiterea valorii prin referință, C# permite de asemenea folosirea cuvântului cheie ref pentru a returna o referință dintr-o metodă și a defini o variabilă care va stoca o referință.

Variabilă de tip referință

Pentru a defini o variabilă locală de tip referință (ref local), înainte de tipul ei se adaugă cuvântul cheie ref:

int x = 5;
ref int xRef = ref x;

Aici variabila xRef indică nu doar valoarea variabilei x, ci și zona din memorie unde se află această variabilă. Pentru aceasta, înainte de x se adaugă de asemenea cuvântul ref.

Nu putem pur și simplu să definim o variabilă de tip referință, trebuie să îi atribuim neapărat o valoare. Astfel, următorul cod va genera o eroare:

ref int xRef;   // eroare

Obținând o referință, putem manipula valoarea prin această referință. De exemplu:

int x = 5;
ref int xRef = ref x;
Console.WriteLine(x); // 5
xRef = 125;
Console.WriteLine(x); // 125
x = 625;
Console.WriteLine(xRef); // 625

Referința ca rezultat al unei funcții

Pentru a returna o referință dintr-o funcție, în semnătura funcției, înainte de tipul returnat și după operatorul return, se adaugă cuvântul cheie ref:

int[] numbers = { 1, 2, 3, 4, 5, 6, 7 };
ref int numberRef = ref Find(4, numbers); // căutăm numărul 4 în array
numberRef = 9; // înlocuim 4 cu 9
Console.WriteLine(numbers[3]); // 9

ref int Find(int number, int[] numbers)
{
   for (int i = 0; i < numbers.Length; i++)
   {
       if (numbers[i] == number)
       {
           return ref numbers[i]; // returnăm referința la adresa, nu valoarea
       }
   }
   throw new IndexOutOfRangeException("numărul nu a fost găsit");
}

În metoda Find căutăm un număr în array, dar în loc să returnăm valoarea numărului, returnăm referința la acesta în memorie. Pentru aceasta, în semnătura metodei ca tip de rezultat se specifică nu doar int, ci ref int.

În plus, în metoda propriu-zisă, după cuvântul return se adaugă ref:

return ref numbers[i];

Astfel obținem nu doar valoarea, ci și referința la obiectul din memorie.

În metoda Main, pentru a defini o variabilă care va conține referința, se folosește cuvântul cheie ref. La apelul metodei se specifică de asemenea cuvântul ref:

ref int numberRef = ref Find(7, numbers);

În final, variabila numberRef va conține referința la un obiect de tip int și prin această variabilă putem modifica ulterior obiectul respectiv.

Un alt exemplu - returnarea referinței la numărul maxim dintre două numere:

int a = 5;
int b = 8;
ref int pointer = ref Max(ref a, ref b);
pointer = 34;   // modificăm valoarea numărului maxim
Console.WriteLine($"a: {a}  b: {b}"); // a: 5   b: 34

ref int Max(ref int n1, ref int n2)
{
   if (n1 > n2)
       return ref n1;
   else
       return ref n2;
}

Este important de remarcat faptul că parametrii metodei în acest caz sunt definiți cu cuvântul cheie ref.

La definirea unei metode care returnează o referință, trebuie avut în vedere că o astfel de metodă nu poate avea tipul void. În plus, o astfel de metodă nu poate returna:

  • Valoarea null
  • O constantă
  • Valoarea unui enum
  • Proprietatea unei clase sau structuri
  • Un câmp doar pentru citire (care are modificatorul read-only)
← Lecția anterioară Lecția următoare →