Een stappenplan, en dus een methode, voer je uit met het oog op een bepaald resultaat. Soms moet dat resultaat terugbezorgd worden aan een opdrachtgever. Soms niet. Methodes staan toe beide variaties op een stappenplan te schrijven.
We gebruiken opnieuw een proces uit het echte leven om de interactie te omschrijven voor we de sprong maken naar code.
Denk aan een ouderwetse bakker. Het stappenplan dat deze bakker volgt is er een om brood te maken. Om brood te maken heb je bloem nodig. Bloem maken is niet echt een onderdeel van het takenpakket van de bakker. Hij laat de molenaar dit voor hem doen. Hij vraagt niet gewoon aan de molenaar om bloem te maken, maar ook om deze aan hem te bezorgen zodat hij er zelf mee verder kan werken. De bakker is niet geïnteresseerd in hoe de molenaar bloem maakt, maar hij heeft het eindproduct nodig om zijn brood af te maken.
We vertalen nu deze interactie naar code en verklaren daarna de vertaling:
Dit is maar een voorbeeld om de flow te verduidelijken. Er is geen "juiste" manier om een methode te schrijven om brood te bakken (tenzij je misschien een broodmachine programmeert).
Hier vallen twee zaken op: in de signatuur (d.w.z. alles van het begin van de regel tot en met het gesloten ronde haakje) van de methode Molenaar staat niet void
, maar string
. Dit komt omdat deze methode een resultaat teruggeeft aan de opdrachtgever en dat resultaat van het type string
is. Daarnaast heb je het sleutelwoord return
, gevolgd door de tekst "bloem"
. Het woordje return
betekent: "bezorg dit aan de code die deze methode heeft opgeroepen". Anders gezegd: dit is hoe de molenaar de geproduceerde bloem overhandigt aan zijn opdrachtgever, de bakker. Waar je de call Molenaar()
schrijft komt tijdens de uitvoering het geproduceerde resultaat dankzij die return
.
return
typeJe moet dus noteren wat voor resultaat er achter return
staat: een string of eventueel iets anders. Als er een string volgt na return
, zeggen we dat string het return type is van die methode. Als een methode een geheel getal produceert, heeft ze het return type int
of een verwant getaltype.
Maar niet alle methodes bezorgen iets terug aan hun opdrachtgever. Sommige hebben gewoon een effect. Voor deze methodes schrijven we void
als return type. Als een methode dit return type heeft, kunnen we het resultaat van een call dus niet toekennen aan een variabele, want er is geen resultaat.
"Er is geen resultaat" wil niet zeggen dat een void
methode niets doet. Console.WriteLine is bijvoorbeeld een methode met return type void
. Het punt is dat de call je niets terugbezorgt waarmee je verder kan werken. Je kan bijvoorbeeld niet schrijven: string tekst = Console.WriteLine("Dit is tekst");
Er is dus een groot verschil tussen return "tekst";
en Console.WriteLine("tekst");
Bij de eerste code is er geen garantie dat de geproduceerde tekst ooit op het scherm verschijnt, maar je kan er wel mee verder werken. Bij de tweede verschijnt hij per definitie wel op het scherm, maar kan je hem niet toekennen aan een variabele om later mee verder te werken.
We kunnen dus wel doen: string ingredient3 = Molenaar();
(want het return type van Molenaar()
is string
) maar we kunnen niet schrijven: string product = Bakker();
(want Bakker()
heeft return type void
en produceert dus geen resultaat). Deze code compileert dan ook niet.
Je kent de methode Replace
van strings. Je gebruikt deze als volgt:
Veel beginners doen het volgende:
Dit is fout. Replace
berekent het resultaat van de aanpassing en geeft dat terug aan de opdrachtgever. Het past de ingevoerde tekst niet aan. In de code van Replace
staat dus ook een return
!
Als je parameters en returnwaarden combineert, worden methoden erg flexibel. Dan kan je al echte bouwsteentjes van een programma gaan schrijven.
Een voorbeeld: de stelling van Pythagoras vertelt ons hoe lang de schuine zijde van een driehoek met twee rechte hoeken is:
Als we deze berekening regelmatig uitvoeren voor verschillende waarden van a
en b
, kunnen we ze als volgt in een methode gieten:
Nu kunnen we heel snel allerlei schuine zijdes uitrekenen, bv.:
Bovendien maken we gebruik van het feit dat de methode Sqrt
(square root is vierkantswortel) ook een parameter heeft en een resultaat teruggeeft. Eigenlijk verloopt een uitvoering dus zo:
de methode Main
start op
we willen bepaalde tekst uitprinten, maar we moeten die eerst nog bepalen met de methode Pythagoras
de methode Pythagoras
start op met de argumenten 4 en 3
de methode berekent de som van de kwadraten en noemt deze som
de methode maakt zelf gebruik van nog een methode, Sqrt
, en geeft daarbij som als argument
Sqrt
rekent de vierkantswortel uit en geeft deze terug aan Pythagoras
Pythagoras
geeft deze verder door aan Main
de zin wordt correct afgeprint
Meestal is het dus een goed idee zo weinig mogelijk informatie te communiceren met WriteLine
en zo veel mogelijk met return
te werken. Meerbepaald: gebruik WriteLine wanneer je de uiteindelijke informatie in haar uiteindelijke vorm hebt en deze echt aan de gebruiker moet tonen. Gebruik return
wanneer je het resultaat van een deeltaak aan een opdrachtgever wil bezorgen.
Volgend Flowgorithm toont aan hoe je dankzij methoden een probleem kan opbreken in meerdere kleine stappen, waarbij je informatie doorgeeft via parameters en returnwaarden: