|
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
Tot nu toe hadden we steeds parameters van eenvoudige datatypes in onze methods gedefinieerd, maar ook instanties van complexere datatypes als arrays kunnen worden doorgeven aan methods.
Dit kan eenvoudig weg door een arrayvariabele te definiëren in de parameterlijst van die methoddefinitie.
Belangrijk is steeds in gedachte te houden dat een arrayvariabele niet de array zelf bevat, maar een verwijzing/referentie bevat naar een arrayinstantie. Wordt zoals in onderstaand voorbeeld numbers als argumentwaarde gebruikt dan zal de argumentvariabele values hier werken met een kopie ( ByVal ) van die doorgegeven referentie. Tijdens uitvoering van deze procedure ( PrintArray ) wijzen beide variabelen ( numbers en values ) naar dezelfde arrayinstantie in het geheugen. Visual Basic 2010 Broncode Module Example1 Sub Main() Dim numbers As Integer() = {1, 2, 3, 4, 5} PrintArray(numbers) Dim words As String() = { "Hello", "World"} PrintArray(words) Dim dates As Date() PrintArray(dates) PrintArray( Nothing) Console.ReadLine() End Sub Sub PrintArray( ByVal values As Array) If values IsNot Nothing Then For Each element As Object In values Console.Write(element & " ") Next Console.WriteLine() Else Console.WriteLine( "No array.") End If End SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output 1 2 3 4 5
Hello World
No array.
No array. Zoals we reeds eerder hadden gezien, kunnen referenties van eender welk soort array gestockeerd worden in een variabele gedeclareerd van het datatype Array. Aan de procedure PrintArray kan elke referentie van een array ( van eender welke soort ) worden doorgegeven. 8.11.1. Datatype ObjectIn For Each ... Next iteratiestructuur van de implementatie van procedure PrintArray wordt hier gewerkt met een elementvariabele van het datatype Object. Het Object datatype is bijzonder in de zin dat men aan een variabele van dit datatype eender welke waarde ( van eender welk datatype ) kan toekennen. Het gebruik van deze Object elementvariabele was voor de procedure PrintArray noodzakelijk gezien we niet weten welk soort van array zal worden doorgespeeld aan deze procedure. De elementvariabele in de For Each ... Next iteratie structuur zou dus bijvoorbeeld van zowel het Integer, als het String, als het Boolean datatype kunnen zijn. Door deze elementvariabele van het type Object te declareren kan het dus omgaan met waarden van al deze datatypes. Visual Basic 2010 Broncode Module Example2 Sub Main() Dim object1 As Object object1 = 5 Console.WriteLine(object1) Console.WriteLine(object1 + 10) object1 = "Hello" Console.WriteLine(object1) Console.WriteLine(object1 & " World !") object1 = True Console.WriteLine(object1) Console.WriteLine(object1 OrElse False) Console.ReadLine() End SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output 5
15
Hello
Hello World !
True
True Werk echter niet te pas en te onpas met het Object datatype. Er zijn bepaalde nadelen verbonden aan het gebruik van dit datatype ( zoals "late binding", "(un)boxing", ... ). Gebruikt steeds "strong typing" ( het uitkiezen van het meest toepasselijke datatype ) en gebruik Object enkel indien strikt noodzakelijk. Lees de topics over value versus reference types en early versus late bound objects voor meer informatie. boven
8.11.2. Vergelijken van Referenties - Is en IsNot OperatorenExample1 maar ook onderstaand voorbeeld demonstreren hoe je na kan gaan of meerdere variabele van "referencetype" datatype verwijzingen bevatten naar dezelfde instantie.
Het vergelijken van referenties kan aan de hand van de Is en IsNot operatoren. Dit in tegenstelling tot het vergelijken van waarden van meer primitieve datatypes, waar de vergelijkingsoperatoren = en <> gebruikt worden. Visual Basic 2010 Broncode Module Example3 Sub Main() Dim values1 As Integer() = {1, 2, 3} Dim values2 As Integer() = {4, 5, 6} Dim values3 As Integer() = values1 Dim values4 As Array = values2 Console.WriteLine(values1 IsNot values2) Console.WriteLine(values1 Is values3) Console.WriteLine(values1 IsNot values4) Console.WriteLine() Console.WriteLine(values2 IsNot values1) Console.WriteLine(values2 IsNot values3) Console.WriteLine(values2 Is values4) Console.ReadLine() End SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output True
True
True
True
True
True De expressie : numbers1 IsNot numbers2 Kan ook als volgt geformuleerd worden : Not numbers1 Is numbers2 In Example1 wordt in de procedure PrintArray - voor het itereren over de elementen van de collectie array - eerst nagegaan of array wel een referentie bevat van een tabel. Het is immers mogelijk dat de arrayvariabele - wordt gebruikt om de argumentwaarde voor te stellen - Nothing bevat ( of dus niet naar een tabelinstantie verwijst ) (1). Een For Each ... Next zal een fout opleveren in deze situatie.
Of men al dan niet dergelijke controle inbouwt is afhankelijk van hoe defensief men wenst te coderen. Vele programmeurs hebben de neiging om de implementaties van hun routines vol controles - doorgaans op de ontvangen argumentwaarden - te proppen, en dus heel defensief te werk te gaan. Dit heeft als voordeel dat men heel robuuste functionaliteiten ontwikkelt, die voorzien zijn op allerhande uitzonderlijke situaties. Dit hoeft niet altijd perse te gebeuren. Men kan er ook simpelweg van uit gaan dat een method enkel correct zal functioneren indien een "correct" input wordt voorzien. Men zou bijvoorbeeld kunnen stellen dat PrintArray vereist dat de doorgegeven array wel degelijk bestaat, en enkele garanderen dat in deze ( "correct" ) situatie de method "correct" zijn verantwoordelijkheid zal vervullen. In deze redenering plaats men de verantwoordelijkheid voor het voorzien van "correct" input naar de aanroepende code. Als de aanroepende code hierbij geen rekening houdt dan is dat zijn probleem. boven
8.11.3. Array als ParameterWe weten ondertussen dat men bij het doorgeven van een array aan een method dus eigenlijk de arrayreferentie doorgeeft en niet de array zelf. Visual Basic 2010 Broncode Module Example4 Sub Main() Dim values As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} Example1.PrintArray(values) DoubleIntegerValues(values, 5) Example1.PrintArray(values) ResizeIntegerArray(values, 20) Example1.PrintArray(values) Console.ReadLine() End Sub Sub DoubleIntegerValues( ByVal values As Integer(), ByVal count As Integer) For index As Integer = 0 To count - 1 values(index) *= 2 Next End Sub Sub ResizeIntegerArray( ByRef values As Integer(), ByVal capacity As Integer) ReDim values(capacity - 1) End SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output 1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 6 7 8 9 10
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 In bovenstaand voorbeeld zal bij uitvoering van de DoubleIntegerValues procedure de variabele values uit Main en de variabele values uit DoubleIntegerValues naar dezelfde tabelinstantie verwijzen. values uit DoubleIntegerValues werkt immers met een kopie van de ontvangen waarde ( een referentie van de values tabel uit Main.
Het volstaat voor de procedure DoubleIntegerValues om te beschikken over dergelijke kopie van de originele tabel om de inhoud van deze tabel te kunnen aanpassen, daarom ByVal.
De procedure ResizeIntegerArray echter wenst de ontvangen tabel te "resizen". Hiervoor kan in zijn implementatie gebruik worden gemaakt van een ReDim statement. Zoals we ondertussen weten zal hierbij een nieuwe tabelinstantie gecreëerd worden, en zal de referentie van deze nieuwe instantie worden toegekend aan de variabele waarnaartoe verwezen wordt in dat ReDim statement. De inhoud van de variabele values uit Main moet hier dus gewijzigd zijn na uitvoer van de ResizeIntegerArray procedure. Dit kan enkel door "by reference" ( ByRef ) te werken met de ontvangen argumentwaarde.
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
|