Nivelul 3 — Funcții
Transmitere prin valoare versus transmitere prin referință
Note originale de SunDiaL · Vezi sursa în engleză
Partea a doua a poveștii care creează confuzie. Și transmiterea parametrilor se împarte în două categorii; împreună cu tipurile valoare și tipurile referință, rezultă patru combinații.
Transmiterea prin valoare
Acesta este modul obișnuit de transmitere a parametrilor. Variabilei parametrului i se atribuie o copie a valorii.
- Pentru tipurile valoare, se copiază valoarea în sine.
- Pentru tipurile referință, se copiază adresa obiectului. Este același lucru ca transmiterea prin pointer în C++.
Transmiterea prin referință
Celălalt mod de transmitere a parametrilor.
- În acest caz, obiectul este folosit „direct”.
Este același lucru ca transmiterea prin referință în C++; reține însă că referințele din C# nu sunt exact același lucru ca referințele din C++.
Pentru o explicație mai detaliată despre referințele din C++, vezi Pointer versus referință.
Este dificil de explicat fără să vezi cum funcționează, iar exemplele necesită cunoștințe despre clase, așa că revino la ele mai târziu.
Exemple
1. Tip valoare transmis prin valoare
void ByVal(int x)
{
x++;
Console.WriteLine(x);
}
void Main()
{
int x = 1;
ByVal(x); // will print 2
Console.WriteLine(x); //will print 1, because there are now two "1" objects sitting in memory. One for the x in main, and one for the x in ByVal.
}
2. Tip valoare transmis prin referință
void ByRef(ref int x)
{
x++;
Console.WriteLine(x);
}
void Main()
{
int x = 1;
ByVal(ref x); // will print 2
Console.WriteLine(x); //will print 2, because x in ByRef uses the the object itself, not a copy.
}
3. Tip referință transmis prin valoare
class Test
{
public int val;
}
void ByValIncrement(Test x)
{
x.val++
Console.WriteLine(x.val);
}
void ByValIncrement(Test x)
{
x = new Test();
x.val = 3;
Console.WriteLine(x.val);
}
void Main()
{
Test x = new Test();
x.val = 1;
ByValIncrement(x); // will print 2
Console.WriteLine(x.val); //will print 2, because the same address was used.
ByValChange(x) //will print 3.
Console.WriteLine(x.val); //will print 2, because the object was changed inside the function.
}
4. Tip referință transmis prin referință
class Test
{
public int val;
}
void ByValIncrement(ref Test x)
{
x.val++
Console.WriteLine(x.val);
}
void ByValIncrement(ref Test x)
{
x = new Test();
x.val = 3;
Console.WriteLine(x.val);
}
void Main()
{
Test x = new Test();
x.val = 1;
ByValIncrement(ref x); // will print 2
Console.WriteLine(x.val); //will print 2, because the same object was used.
ByValChange(ref x) //will print 3.
Console.WriteLine(x.val); //will print 3, because the object was used "directly".
}