Ce face ref, out și in
Implicit, C# transmite argumentele prin valoare: metoda primește o copie, iar schimbarea ei nu afectează variabila apelantului. Cu ref, metoda lucrează direct pe variabila apelantului, care trebuie să fie inițializată înainte de apel.
out este pentru valori de ieșire: variabila nu trebuie inițializată, dar metoda este obligată să-i dea o valoare înainte să se încheie. E modelul folosit de int.TryParse și Dictionary.TryGetValue. Variabila se poate declara direct la apel: out var rezultat.
in transmite prin referință doar pentru citire, ca să eviți copierea unor struct-uri mari. Pentru un singur rezultat suplimentar, de multe ori un tuple returnat e mai simplu decât out.
Parametri
| Parametru | Descriere |
|---|---|
ref |
Citire și scriere; argumentul trebuie inițializat. La apel se scrie ref. |
out |
Doar ieșire; metoda trebuie să atribuie valoarea. La apel se scrie out. |
in |
Doar citire, fără copiere. La apel in e opțional. |
Exemple
Exemplul 1: Valoare vs. ref
int sold = 100;
AdaugaCopie(sold, 50);
Console.WriteLine(sold);
AdaugaRef(ref sold, 50);
Console.WriteLine(sold);
static void AdaugaCopie(int valoare, int suma) => valoare += suma;
static void AdaugaRef(ref int valoare, int suma) => valoare += suma;
Rezultat
100
150
Exemplul 2: out pentru o metodă de tip Try
Metoda returnează bool (a reușit sau nu), iar valoarea propriu-zisă vine prin out.
string[] intrari = ["Iași:700000", "Cluj", "Arad:fără"];
foreach (string text in intrari)
{
if (IncearcaCitire(text, out string oras, out int locuitori))
Console.WriteLine($"{oras} are {locuitori} locuitori");
else
Console.WriteLine($"Format greșit: {text}");
}
static bool IncearcaCitire(string text, out string oras, out int locuitori)
{
string[] parti = text.Split(':');
oras = parti[0];
locuitori = 0;
return parti.Length == 2 && int.TryParse(parti[1], out locuitori);
}
Rezultat
Iași are 700000 locuitori
Format greșit: Cluj
Format greșit: Arad:fără
Greșeli frecvente
- Uitarea cuvântului
refsauoutla apel:AdaugaRef(sold, 50)nu se compilează. - O metodă cu
outcare iese fără să atribuie parametrul dă eroarea CS0177. - Metodele
asyncși iteratorii (yield) nu pot avea parametriref,outsauin. Returnează un tuple în loc.
Comenzi înrudite
Metode (static, void, return): O metodă grupează cod reutilizabil sub un nume: primește parametri, poate returna o valoare cu return sau nimic (void).int.Parse și int.TryParse: Transformă text în număr: Parse aruncă excepție la text invalid, TryParse returnează false și nu aruncă.Tuple-uri și deconstrucție: Grupează câteva valori fără să declari o clasă: (string Nume, int Varsta), cu deconstrucție în variabile separate.struct: Tip valoare: se copiază la atribuire și la transmitere, nu are null și e potrivit pentru date mici și imutabile.