Har man brug for at få værdier ud af en funktion kan man
naturligvis bruge funktionens returværdi, hvilket er oplagt i de
fleste tilfælde. Der kan dog være tilfælde, hvor man har brug for
at returnere flere værdier fra en funktion og i disse tilfælde har
man et par yderligere muligheder.
out-parametre
Med out-parameteren kan man sende en værdi ud af et
funktionskald. Parameteren SKAL tildeles en værdi inde i
funktionen, ellers får man en compilefejl. Parameteren er KUN
til output, evt. værdi i input vil blive ignoreret. Følgende
vil give en compilefejl (fordi p endnu ikke er tildelt en værdi
inde i fn, inden den refereres):
void fn(out int p)
{
return p + 1;
}
var x = 1;
fn(out x);
Samtidig opfattes denne parameter alene som en output-parameter,
dvs. den værdi parameteren evt. måtte have i kaldet, kan ikke
bruges i funktionen. Følgende vil f.eks. give en kørselsfejl, fordi
parameteren p ikke er tildelt en værdi inden den bruges (inde i
funktionen):
void fn(out int p)
{
Console.WriteLine(p);
p = 2;
}
var x = 10;
fn(out x);
ref-parametre
Med ref-parametre kan man sende værdier ind i en funktion og
samtidig give funktionen mulighed for at ændre værdien af den
parametere (så den også ændres i den kaldende parts variabel).
Dette kunne se således ud:
void fn(ref int p)
{
p++;
}
var x = 1;
fn(ref x);
// x er nu 2;
Denne måde at bruge ref på, kan være "farlig" og betragtes af
mange som dårlig kodestil. Begrundelsen er, at kaldet til fn har en
skjult sideeffekt på den kaldende parts kode. Denne
sideeffekt er svær at forudse, hvis man ikke lige har adgang
til koden i fn og kan se hvad der sker. Selvom man havde adgang til
koden, var det ikke nødvendigvis let at gennemskue denne
sideeffekt alligevel. Det er derfor ikke tilrådeligt, at benytte
ref på denne måde.
Når ref-modifikatoren bruges er det den variabel som står
på parameterens plads i kaldet, der ændres (direkte i den
hukommelsesplads variablen ligger). Det betyder også, at når der
medsendes en referencevariabel (bla. objekter, strenge, arrays), så
er det referencen der ændres, dvs. der peges på en anden forkomst
af den medsendte type. Dette er fordi referencevariable i sig selv
er referencer (navnet havde nok allerede afsløret dette) og det er
altså pegepinden der ændres.
Det samme gælder for simple typer, hvor værdien ændres direkte i
den hukommelsesposition, hvor variablen er defineret inden kaldet
til funktionen.
Hukommelsespositionen kan dels være på "heapen", dels på
stakken. Stakken benyttes hvis kaldet sker med en lokal
variabel fra en anden funktion.