1. Introduktion

I CSharp finns det två huvudgrupper av typer. Den ena är fördefinierade primitiva datatyper och den andra är klasstyper. Vi hör ofta att den förra är värdetyp och den senare referenstypen . I den här artikeln kommer vi att undersöka hur dessa typer beter sig när de överförs till en funktion som värde och som referens.

2. Point2D-klassen

Denna klass innehåller två medlemsvariabler (x, y). Dessa medlemmar representerar koordinaten för en punkt. En konstruktör som tar två parametrar från den som ringer initierar dessa två medlemmar. Vi använder SetXY-funktionen för att göra en ändring av medlemmarna. Utskriftsfunktionen skriver aktuell koordinat till fönstret Console Output.

Vi kommer att skapa instanser av den här klassen för att utforska olika parametrar som passerar tekniker. Kod för denna klass visas nedan:

 // Exempel 01: En enkel Point Class offentlig klass Point2D {privat int x; privat int y; public Point2D (int X, int Y) {x = X; y = Y; } public void Setxy (int Valx, int Valy) {x = Valx; y = Valy; } public void Print () {Console.WriteLine ("Innehåll i Point2D:" + x + ", " + y); }} 

Vi kommer att introducera ytterligare en klass som heter TestFunc. Detta är en statisk klass och kommer att ha alla våra testfunktioner för att utforska olika metodpasseringsmetoder. Klassens skelett är nedan:

 statisk klass TestFunc {} 

3. Primitiva typer

En primitiv typ är en fördefinierad datatyp som kommer med språket och representerar direkt en basdata som ett heltal eller ett tecken. Ta en titt på koden nedan:

 ogiltigt AFunctionX () {int p = 20; } 

I ovanstående funktion har vi bara en variabel som heter F. Den lokala stapelramen för funktionen AFunctionX fördelar utrymme för variabeln F för att lagra värdet 15. Titta på nedanstående bild

Primitiv datatyp allokerad på stack |

I bilden ovan kan vi se att stapelramen känner till att det finns en variabel p genom dess basadress (till exempel 0x79BC) på stapelramen och kartlägger den till den faktiska adressplatsen 0x3830 på samma stapelram vid en viss offset. Värdet 20 tilldelat i funktionen lagras på Stack Memory Location, 0x3830. Vi kallar detta som ett variabelt namnbindande eller helt enkelt "namnbindande" . Här är namnet p bundet till adressen 0x3830. Varje läs- eller skrivbegäran på p sker på minnesplatsen 0x3830.

Låt oss nu utforska olika sätt att överföra primitiva datatyper till en funktion och dess beteende.

3.1 Primitiva typer - Pass by Value

Vi definierar funktionen nedan i den statiska klassen TestFunc. Denna funktion tar ett heltal som ett argument. Inuti funktionen ändrar vi värdet på argumentet till 15.

 // Exempel 02: Funktion som tar argument // Pass By Value public static void PassByValFunc (int x) {// Print Value Receive Console.WriteLine ("PassByValFunc: Receiving x" + "by Value. Värdet är: {0}", x); // Ändra värdet på x och Skriv ut x = 15; // Skrivmottagningskonsol.WriteLine ("PassByValFunc: Efter att ha ändrat" + "värde, x =" + x); } 

Vi kallar ovan definierad funktion från vårt huvudprogram. Först förklarar och initialiserar vi en heltalvariabel. Innan ett samtal till funktionen är värdet på heltalet 20 och vi vet att funktionen ändrar detta värde till 15 i sin kropp.

 // Prov 03: Test Pass by Value // Standardvariabler int p = 20; Console.WriteLine ("Main: Innan du skickar p" + "efter värde. Värdet i p är: {0}", p); TestFunc.PassByValFunc (p); Console.WriteLine ("Main: Efter att ha ringt" + "PassByValFunc efter värde. Värdet i" + "p är: {0}", p); Console.WriteLine (); 

Utdata från denna enkla kod anges nedan:

Standardtyper - Output by Value Output |

Här ändrar funktionen PassByValFunc det överförda i parametervärdet från 20 till 15. När funktionen återkommer, behåller huvudet fortfarande värdet 20. Nu, titta på nedanstående bild.

Primitiv typövergång - förklarat |

Först ska vi titta på den övre delen av bilden. Bilden visar att vår körning förblir vid första uttalandet som markeras med gult. I detta skede har samtalstackens huvuddel ett namn p definierat vid 79BC som binder till plats 3830. Innan den kallade denna funktion använde huvudprogrammet namnet p för att tilldela ett värde på 20 i minnesplatsen 3830 vilken stapelram. Den kallade funktionen definierar namn x i sin egen stapelram på plats 9796 och som binder till minnesplatsen 773E. Eftersom parametern skickas efter värde, inträffar en kopia mellan p till x. Med andra ord, innehållet i plats 3830 kopieras till platsen 773E.

Nu ska vi utforska den nedre delen av bilden. Utförandet går till det sista uttalandet. Vid denna tid har vi redan utfört uppdraget (x = 15) och därmed ändras innehållet i 773E till 15. Men stapelramens placering 3830 för main ändras inte. Det är därför vi ser huvudutskrift p som 20 efter funktionssamtalet.

3.2 Primitiva typer - Pass by Reference med Ref-nyckelord

I föregående avsnitt såg vi passera ett argument efter värde och vi passerade faktiskt en primitiv typ som en parameter. Nu kommer vi att undersöka beteendet genom att skicka samma primitiva datatyp som en referens. Vi skrev en funktion i vår statiska klass för att få argumentet genom referens . Koden är nedan:

 // Exempel 04: Funktion med argumenter // Pass By Reference (Ref) public static void PassByRefFunc (ref int x) {// Print Value Receive Console.WriteLine ("PassByRefFunc: Tar emot x" + "efter värde. Värdet är: {0} ", x); // Ändra värdet på x och Skriv ut x = 45; // Skriv ut det ändrade värdet Console.WriteLine ("PassByRefFunc: Efter att ha ändrat" + "värde, x =" + x); } 

Vi bör notera användningen av sökordet "ref" i funktionen Argumentlista. I den här funktionen ändrar vi det överförda värdet till 45 och skriver ut innehållet i namnet x före och efter modifiering. Nu skriver vi en samtalskod i huvudprogrammet som visas nedan:

 // Prov 05: Test Pass by Reference // Standardvariabler (ref) int r = 15; Console.WriteLine ("Main: Innan du skickar r" + "med referens. Värdet i r är: {0}", r); TestFunc.PassByRefFunc (ref r); Console.WriteLine ("Main: Efter att ha ringt" + "PassByValFunc efter värde. Värdet i" + "r är: {0}", r); Console.WriteLine (); 

Här tilldelar vi först en heltalvariabel med ett värde av 15. Därefter kallar vi funktionen och passerar variabeln med referens. Vi bör notera användningen av nyckelordet ref här. Vi måste ange ref-nyckelordet både i den anropade funktionens argumentlista samt i parameterlista med anropskod. Nedanstående skärmdump visar utdata från denna kodkod:

Standardtyper - Pass by Ref Output |

Genom att titta på utgången kan vi undra varför huvudfunktionen är utskriftsvärdet för r är 45 som ändrades i den kallade funktionen, inte i huvudfunktionen. Nu ska vi utforska det. Kom ihåg att vi passerade parametern genom referens och titta på nedanstående skildring:

Primitiv typövergång - förklarad |

Den övre delen av bilden visar att exekveringen förblir högst upp i funktionen innan värdet på x ändras. I detta skede är huvudstapelramens adress 3830 associerad med namnet r och har ett värde 15. Det finns ingen skillnad här när vi passerar parametern efter värde eller med referens. Men i den kallade funktionen Stack Frame är inget minne reserverat för x. Här binder x också till den anropande stackplatsen 3830 på grund av omnämnandet av ref-nyckelordet. Nu är minnesplatsen för huvudfunktionsstapelramen 3830 bunden av två namn r och x.

Nu ska vi utforska den nedre delen av skildringen. Utförandet förblir i slutet av funktionen och det ändrade stapelramens plats till 45 genom namnet x. Eftersom x och r båda binder till minnesplatsen 3839 ser vi huvudfunktionstryckning 45 i utgångsresultatet. Så när vi passerar en primitiv typvariabel som referens reflekteras innehållet i den kallade funktionen i huvudfunktionen. Observera att bindningen (x bindning till plats 3830) skrapas efter att funktionen återgår.

3.3 Primitiva typer - Pass by Reference med ut sökord

När vi passerar en parameter genom referens med omnämnande av ref sökord, förväntar kompilatorn att parametern redan initierades. Men i vissa situationer förklarar samtalsfunktionen bara en primitiv typ och den kommer att tilldelas först i den kallade funktionen. För att hantera denna situation introducerade c- Sharp out nyckelordet som anges i funktionssignaturen och samtidigt som den kallade den funktionen.

Nu kan vi skriva nedan angiven kod i vår statiska klass:

 // Exempel 06: Funktion med argumenter // Pass By Reference (out) public static void PassByrefOut (out int x) {// Tilldela värde inuti funktionen x = 10; // Skriv ut det ändrade värdet Console.WriteLine ("PassByRefFunc: Efter att ha ändrat" + "värde, x =" + x); } 

I koden tilldelar vi ett värde 10 till den lokala variabeln x och trycker sedan ut värdet. Detta fungerar på samma sätt som referens. För att passera en variabel utan initialisering markerade vi parametern x med out nyckelordet. Ut-nyckelordet förväntar sig att den funktionen måste tilldela ett värde till x innan det kommer tillbaka. Låt oss nu skriva samtalskoden som visas nedan:

 // Prov 07: Test Pass by Reference // Standardvariabler (ut) int t; TestFunc.PassByrefOut (out t); Console.WriteLine ("Main: Efter att ha ringt" + "PassByrefOut by Value. Värdet i" + "t är: {0}", t); Console.WriteLine (); 

Variablen t deklareras här och sedan kallar vi funktionen. Vi skickar parametern t med nyckelordet ut. Detta säger kompilatorn att variabeln kanske inte initialiseras här och funktionen tilldelar ett giltigt värde till den. Eftersom out fungerar som pass genom referens kan det tilldelade värdet i den kallade funktionen ses här. Kodens utgång är nedan:

Standardtyper - Pass By Ref med "out" Output |

4. Referenstyper

När vi säger Reference Type, menar vi att minnesplatsen för data lagras av typen. Alla klassinstanser som vi skapar i C-skarp är referenstyp. För bättre förståelse kommer vi att titta på koden nedan

 void AFunctionX () {MyClass obj = new MyClass (); } 

I koden skapar vi en instans av klass MyClass och lagrade dess referens i obj. Med den här variabeln obj kan vi komma åt klassens medlemmar. Nu ska vi titta på beskrivningen nedan:

Hänvisningstilldelning av typ Heap, Adress i stack |

Namnet obj upprätthålls av Stack Frame of function (AFunctionX), binder det till platsen 3830. Till skillnad från primitiv datatyp har minnesplatsen adressen till någon annan minnesplats. Därför kallar vi obj som referenstyp. Observera att platsen i värdetyp borde ha tilldelats ett direkt värde (Ex: int x = 15).

När vi skapar "Klassobjekt" med hjälp av nyckelordet nya eller andra typer med nytt, kommer minnet att anspråkas på högplatsen. I vårt exempel tilldelas minne som krävs för objektet av typen MyClass i högen på plats 5719. Variabeln obj innehar minnesplatsen för den högen och minnet som krävs för att hålla den adressen anges i stacken (3830). Eftersom namnet obj innehar eller hänvisar till heap-platsens adress, kallar vi det som referenstyp.

4.1 Referensstyp - Pass by Value

Nu kommer vi att utforska Pass By Value för en referenstyp. Vi kommer att skriva en funktion i vår statiska klass för det. Funktionen ges nedan:

 // Prov 08: Pass by Value (Object) public static void PassByValFunc (Point2D theObj, int Mode) {if (Mode == 0) {theObj.Setxy (7, 8); Console.WriteLine ("Nytt värde tilldelat inuti" + "PassByValFunc"); theObj.Print (); } annars om (Mode == 1) {theObj = new Point2D (100, 75); Console.WriteLine ("Parameter theObj pekar" + "till Nytt objekt inuti PassByValFunc"); theObj.Print (); }} 

Denna funktion får två argument. Vid denna tidpunkt kan vi svara på att den första parametern är en referenstyp och den andra är värdetyp. När läget är noll, försöker vi att byta data medlemmar i Point2D-instansen. Detta innebär att vi ändrar innehållet i heapminnet. När läget är ett försöker vi tilldela nytt Point2D-objekt och hålla det i variabeln som heter theobj. Detta innebär att vi försöker ändra stacken för att hålla den nya adressen. OK! Nu ska vi titta på samtalskoden:

 // Prov 09: Passing Objects by Value //9.1 Skapa ny 2dPoint Point2D One = new Point2D (5, 10); Console.WriteLine ("Huvud: Point2d Object One skapad"); Console.WriteLine ("Dess innehåll är:"); One.Print (); //9.2 Pass by Value //9.2.1 Ändra endast innehållande värden Console.WriteLine ("Calling PassByValFunc (One, 0)"); TestFunc.PassByValFunc (One, 0); Console.WriteLine ("Efter att ha ringt PassByValFunc (One, 0)"); One.Print (); 

I samtalskoden tilldelar vi först Point2D-objektet på högen och initierar punktkoordinaterna till 5 och 10. Därefter överför vi referensen till detta objekt (One) efter värde till funktionen PassByValFunc.

4.1.1 Ändra innehållet

Det andra argumentet som skickas till funktionen är noll. Funktionen ser läget som noll och ändrar koordinatvärdena till 7 och 8. Titta på nedanstående bild:

Referens Typ - Pass by Value - Ändra hög innehåll |

Vi tittar på den övre halvan av bilden. Eftersom vi passerar referensen (One) efter värde, fördelar funktionen ny plats i bunten på 0x773E och lagrar adressen till heap-platsen 0x3136. I detta skede (När exekvering är på om villkorligt uttalande som markeras ovan) finns det två referenser som pekar på samma plats 0x3136. I moderna programmeringsspråk som C-Sharp och Java, säger vi att referensräkning för heap-platsen är två. Den ena är från Calling-funktionen genom referens En och den andra är från den kallade funktionen via Reference theObj.

Den nedre delen av bilden visar att innehållet i högen ändras genom referensen theObj. Samtalet vi gjorde till funktionen Setxy ändrade innehållet på Heap-platsen som pekas av två referensobjekt. När funktionen återgår, i samtalsfunktionen hänvisar vi till den här ändrade platsen för heapminne genom Namnet “One” som binds till 0x3830. Så här skriver anropsfunktionen 7 och 8 som koordinatvärden.

Utgången från den ovan visade koden är nedan:

Referensstyper Utgång 1 |

4.1.2 Ändring av referens

I föregående avsnitt bad vi funktionen om att ändra värdet på högen genom att lämna noll som ett värde för Mode-argumentet. Nu ber vi funktionen om att ändra själva referensen. Titta på samtalskoden nedan:

 //9.2.2 Ändra själva referensen. Console.WriteLine ("Calling PassByValFunc (One, 1)"); TestFunc.PassByValFunc (One, 1); Console.WriteLine ("Efter att ha ringt PassByValFunc (One, 1)"); One.Print (); Console.WriteLine (); 

För att förklara vad som händer i funktionen måste vi titta på bilden nedan:

Referenstyper - Pass-by-Value - Ändra högplats |

När läget är 1 tilldelar vi ny hög och tilldelar det till det lokala namnet theObj . Nu ska vi titta på den övre delen av bilden. Allt är detsamma som i föregående avsnitt eftersom vi inte berör referensen theObj .

Titta nu på den nedre delen av bilden. Här tilldelar vi den nya högen på plats 0x7717 och initialiserar högen med koordinatvärden 100, 75. På det här stadiet har vi två namnbindningar som heter One och theObj . Namnet One tillhör den anropande stacken som binder till platsen 0x3830, som pekar på den gamla heap-platsen 0x3136. Namn theObj tillhör den kallade Stack Frame-bindningen till platsen stack location 0x773E som pekar på heap location 0x7717. Kodutgången visar 100, 75 inne i funktionen och 5, 10 efter att vi har återvänt från den. Detta eftersom vi läser plats 0x7717 inne i funktionen och efter att vi återvänt läser vi platsen 0x3136.

Observera att när vi har kommit tillbaka från funktionen raderas stapelramen för funktionen och där av stackplatsen 0x773E och adressen 0x7717 lagrad i den. Detta minskar referensräknaren för platsen 0x7717 från 1 till noll som signalerar Garbage Collector om att högplatsen är 0x7717 inte används.

Utgången för att köra koden anges i skärmbilden nedan:

Referenstyper Pass-by-Value Output 2 |

4.2 Referensstyp - Pass by Reference

I det föregående avsnittet undersökte vi att överföra en objektreferens “By Value” till en funktion. Vi kommer att utforska att passera objektreferensen "Med referens". Först kommer vi att skriva en funktion i vår statiska klass och koden för den som anges nedan:

 // Prov 10: Pass by Reference med ref public static void PassByRefFunc (ref Point2D theObj, int Mode) {if (Mode == 0) {theObj.Setxy (7, 8); Console.WriteLine ("Nytt värde tilldelat inuti" + "PassByValFunc"); theObj.Print (); } annars om (Mode == 1) {theObj = new Point2D (100, 75); Console.WriteLine ("Parameter theObj pekar" + "till Nytt objekt inuti PassByValFunc"); theObj.Print (); }} 

Observera, vi specificerade ref sökord i den som en del av den första parametern. Det berättar kompilatorn att Objektreferensen skickas "Med referens". Vi vet vad som händer när vi passerar en värdetyp (primitiva typer) med referens. I det här avsnittet undersöker vi samma för referenstyper med våra Point2D-objektreferenser. Funktionens samtalskod anges nedan:

 // Prov 11: Passing Objects by Reference //11.1 Skapa ny 2dPoint Point2D Two = new Point2D (5, 10); Console.WriteLine ("Huvud: Point2d Object Two skapad"); Console.WriteLine ("Dess innehåll är:"); Two.Print (); //11.2 Pass by Ref //11.2.1 Ändra endast innehållande värden Console.WriteLine ("Calling PassByRefFunc (Two, 0)"); TestFunc.PassByRefFunc (ref Two, 0); Console.WriteLine ("Efter att ha ringt PassByRefFunc (Two, 0)"); Two.Print (); 

4.2.1 Ändra innehållet

Här gör vi samma sak. Men på rad 11 passerar vi objektreferensen "Två" med "ref" sökord. Vi ställer också in läget som 0 för att undersöka beteendet hos förändringarna i höghalten. Titta nu på nedanstående bild:

Referens Typ - Pass by Reference - Ändra hög innehåll |

Den övre delen av bilden visar att det finns två namnbindningar till Calling Stack-platsen 0x3830. Namnet "Två" binder till sin egen Call Stack-plats 0x3830 och namnet "theObj" från den kallade funktionen binder också till samma plats. Stapelplatsen 0x3830 innehåller adressen till högplatsen 0x3136.

Nu ska vi titta på den nedre delen. Vi kallade SetXY-funktionen med nya koordinatvärden 7, 8. Vi använder namnet “theObj” för att skriva in Heap Location 0x3136. När funktionen återgår läser vi samma höginnehåll med namnet “Två”. Nu är vi tydliga varför vi får 7, 8 som koordinatvärden från samtalskoden efter att funktionen återgår. Kodutgången är nedan:

Referenstyper Utgång 1 |

4.2.2 Ändring av referens

I föregående avsnitt ändrade vi Heap-innehållet och undersökte beteendet. Nu kommer vi att ändra stackinnehållet (dvs.) vi tilldelar en ny hög och lagrar adressen på samma stackplats. I samtalskoden ställer vi in ​​läget som 1 som visas nedan:

 //11.2.2 Ändra själva referensen. Console.WriteLine ("Calling PassByRefFunc (Two, 1)"); TestFunc.PassByRefFunc (ref Two, 1); Console.WriteLine ("Efter att ha ringt PassByRefFunc (Two, 1)"); Two.Print (); Console.WriteLine (); 

Titta nu på bilden nedan:

Referenstyper - Pass-by-Reference - Ändra högplats |

Titta nu på den övre delen av bilden. När vi har kommit in i funktionen har heap-platsen två referensräknare Två, theObj. Den nedre delen visar ögonblicksbilden av minnet när exekveringen förblir i utskriftsfunktionen. I detta skede tilldelade vi ett nytt objekt i Heap på plats 0x7717. Sparade sedan denna högadress genom theObj namnbindning. Den anropande stackplatsen 0x3830 (kom ihåg att den har två namnbindningar två, theObj) lagrar nu en ny högplats 0x7717.

Eftersom den gamla heap-platsen skrivs över av den nya adressen 0x7717 och ingen pekar på den, kommer den här gamla heap-platsen att samlas in. Kodutgången visas nedan:

Referenstyper Utgång 2 |

4.3 Hänvisningstyp - Pass by Reference med ut sökord

Uppträdandet är samma som föregående avsnitt. Sedan specificerar vi "ut" vi kan passera referensen utan att initialisera den. Objektet kommer att tilldelas i den uppringda funktionen och ges till den som ringer. Läs beteendet från avsnittet Primitiva typer. Exempel på fullständig kod ges nedan.

Program.cs

 använder System; med hjälp av System.Collections.Generic; med System.Text; namespace PassByRef {class Program {statisk void Main (string [] args) {// Exempel 03: Test Pass by Value // Standardvariabler int p = 20; Console.WriteLine ("Main: Innan du skickar p" + "efter värde. Värdet i p är: {0}", p); TestFunc.PassByValFunc (p); Console.WriteLine ("Main: Efter att ha ringt" + "PassByValFunc efter värde. Värdet i" + "p är: {0}", p); Console.WriteLine (); // Prov 05: Test Pass by Reference // Standardvariabler (ref) int r = 15; Console.WriteLine ("Main: Innan du skickar r" + "med referens. Värdet i r är: {0}", r); TestFunc.PassByRefFunc (ref r); Console.WriteLine ("Main: Efter att ha ringt" + "PassByValFunc efter värde. Värdet i" + "r är: {0}", r); Console.WriteLine (); // Prov 07: Test Pass by Reference // Standardvariabler (ut) int t; TestFunc.PassByrefOut (out t); Console.WriteLine ("Main: Efter att ha ringt" + "PassByrefOut by Value. Värdet i" + "t är: {0}", t); Console.WriteLine (); // Prov 09: Passing Objects by Value //9.1 Skapa ny 2dPoint Point2D One = new Point2D (5, 10); Console.WriteLine ("Huvud: Point2d Object One skapad"); Console.WriteLine ("Dess innehåll är:"); One.Print (); //9.2 Pass by Value //9.2.1 Ändra endast innehållande värden Console.WriteLine ("Calling PassByValFunc (One, 0)"); TestFunc.PassByValFunc (One, 0); Console.WriteLine ("Efter att ha ringt PassByValFunc (One, 0)"); One.Print (); //9.2.2 Ändra själva referensen. Console.WriteLine ("Calling PassByValFunc (One, 1)"); TestFunc.PassByValFunc (One, 1); Console.WriteLine ("Efter att ha ringt PassByValFunc (One, 1)"); One.Print (); Console.WriteLine (); // Prov 11: Passing Objects by Reference //11.1 Skapa ny 2dPoint Point2D Two = new Point2D (5, 10); Console.WriteLine ("Huvud: Point2d Object Two skapad"); Console.WriteLine ("Dess innehåll är:"); Two.Print (); //11.2 Pass by Ref //11.2.1 Ändra endast innehållande värden Console.WriteLine ("Calling PassByRefFunc (Two, 0)"); TestFunc.PassByRefFunc (ref Two, 0); Console.WriteLine ("Efter att ha ringt PassByRefFunc (Two, 0)"); Two.Print (); //11.2.2 Ändra själva referensen. Console.WriteLine ("Calling PassByRefFunc (Two, 1)"); TestFunc.PassByRefFunc (ref Two, 1); Console.WriteLine ("Efter att ha ringt PassByRefFunc (Two, 1)"); Two.Print (); Console.WriteLine (); // Prov 13: Passing Objects by Rerence with Out Key //13.1 Skapa ny 2dPoint Point2D Three; Console.WriteLine ("Main: Point2d Object Three Declared"); Console.WriteLine ("Dess innehåll är: Un-Initialized"); //13.2 Ändra själva referensen. Console.WriteLine ("Calling PassByrefOut (Three)"); TestFunc.PassByrefOut (ut tre); Console.WriteLine ("Efter att ha ringt PassByrefOut (tre)"); Three.Print (); }}} 

TestFunc.cs

 använder System; med hjälp av System.Collections.Generic; med System.Text; namnutrymme PassByRef {// Exempel 01: En enkel punktklass offentlig klass Point2D {privat int x; privat int y; public Point2D (int X, int Y) {x = X; y = Y; } public void Setxy (int Valx, int Valy) {x = Valx; y = Valy; } public void Print () {Console.WriteLine ("Innehåll i Point2D:" + x + ", " + y); }} statisk klass TestFunc {// Exempel 02: Funktion som tar argument // Pass By Value offentligt statiskt tomrum PassByValFunc (int x) {// Skriv ut värde mottaget konsol.WriteLine ("PassByValFunc: Ta emot x" + "efter värde. Värdet är: {0} ", x); // Ändra värdet på x och Skriv ut x = 15; // Skrivmottagningskonsol.WriteLine ("PassByValFunc: Efter att ha ändrat" + "värde, x =" + x); } // Exempel 04: Funktion med argumenter // Pass By Reference (Ref) public static void PassByRefFunc (ref int x) {// Print Value Receive Console.WriteLine ("PassByRefFunc: Receiving x" + "by Value. Value is : {0} ", x); // Ändra värdet på x och Skriv ut x = 45; // Skriv ut det ändrade värdet Console.WriteLine ("PassByRefFunc: Efter att ha ändrat" + "värde, x =" + x); } // Exempel 06: Funktion med argument // Pass By Reference (out) public static void PassByrefOut (out int x) {// Tilldela värde inuti funktionen x = 10; // Skriv ut det ändrade värdet Console.WriteLine ("PassByRefFunc: Efter att ha ändrat" + "värde, x =" + x); } // Exempel 08: Pass by Value (Object) public static void PassByValFunc (Point2D theObj, int Mode) {if (Mode == 0) {theObj.Setxy (7, 8); Console.WriteLine ("Nytt värde tilldelat inuti" + "PassByValFunc"); theObj.Print (); } annars om (Mode == 1) {theObj = new Point2D (100, 75); Console.WriteLine ("Parameter theObj pekar" + "till Nytt objekt inuti PassByValFunc"); theObj.Print (); }} // Exempel 10: Pass by Reference med ref public static void PassByRefFunc (ref Point2D theObj, int Mode) {if (Mode == 0) {theObj.Setxy (7, 8); Console.WriteLine ("Nytt värde tilldelat inuti" + "PassByValFunc"); theObj.Print (); } annars om (Mode == 1) {theObj = new Point2D (100, 75); Console.WriteLine ("Parameter theObj pekar" + "till Nytt objekt inuti PassByValFunc"); theObj.Print (); }} // Exempel 12: Pass by Reference med out public static void PassByrefOut (out Point2D theObj) {theObj = new Point2D (100, 75); Console.WriteLine ("Parameter theObj pekar" + "till Nytt objekt inuti PassByValFunc"); theObj.Print (); }}} 

5. Sammanfattning

Nyckelorden ref och ut handlar om hur staplingsplatsen ”Name-Binding” kan göras. När vi inte anger ref eller ut sökord, binder parametern till en plats i den kallade stacken och en kopia kommer att utföras.