|
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
Het datatype Hashtable is niet bepaald typesafe. Om deze dictionary breed inzetbaar te maken werkt men hier met zowel keys als values van het type Object. Zo verwacht de Add method twee Object argumenten en levert de Item method een value in Object vorm op.
Het voordeel hiervan is dat men bijvoorbeeld heel eenvoudig values van verschillende datatypes kan toevoegen : Visual Basic 2010 Broncode Namespace Example1 Class Client Public Shared Sub Main() Dim integerValue As Integer = 1 Dim stringValue As String = "two" Dim charValue As Char = "3"c Dim personValue As Person = New Person Dim hashtable1 As New Hashtable hashtable1.Add(1, integerValue) hashtable1.Add(2, stringValue) hashtable1.Add(3, charValue) hashtable1.Add(4, personValue) Console.WriteLine( DirectCast(hashtable1.Item(4), Person).Name) End Sub End Class Class Person Private _Name As String Public Property Name() As String Get Name = _Name End Get Set( ByVal value As String) _Name = value End Set End Property End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Object is immers het supertype, expressies van dit type kunnen verwijzen naar eender welk object, van eender welk type.
Dit is natuurlijk enkel een voordeel indien dit de bedoeling is. Indien het uitgangspunt echter is dat de collectie voor values dient te werken van één bepaald datatype, dan is dit uiteraard een nadeel.
Vervelend is ook hoe bijvoorbeeld de expressie hashtable1.Item(4) het Person element in Object vorm oplevert. Om van de Name property van dit Person element gebruik te kunnen maken, moeten we deze Object expressie dan nog eens casten in Person vorm.
Aan het Object datatype zijn nog andere nadelen verbonden, boxing en unboxing bijvoorbeeld indien de Object expressie naar een valuetype instantie verwijst.
Om van bovenstaande nadelen af te geraken kan je gebruik maken van de generieke Dictionary(Of TKey, TValue). Als bijvoorbeeld een dictionary nodig is waarbij alle keys Square objecten zijn, en alle values String objecten zijn, kan je werken met de strongly typed Dictionary(Of Square, String) : Visual Basic 2010 Broncode Namespace Example2 Enum File FileA FileB End Enum Enum Rank Rank1 Rank2 End Enum Class Square Public Sub New( ByVal file As File, ByVal rank As Rank) _File = file _Rank = rank End Sub Private ReadOnly _File As File Public ReadOnly Property File() As File Get File = _File End Get End Property Private ReadOnly _Rank As Rank Public ReadOnly Property Rank() As Rank Get Rank = _Rank End Get End Property Public Overrides Function ToString() As String ToString = File.ToString() & "-" & Rank.ToString() End Function Public Overrides Function Equals( ByVal obj As Object) As Boolean If obj IsNot Nothing AndAlso TypeOf obj Is Square Then Dim other As Square = DirectCast(obj, Square) Equals = ( Me.Rank = other.Rank AndAlso Me.File = other.File) End If End Function Public Overrides Function GetHashCode() As Integer GetHashCode = File Xor Rank End Function End Class Class Client Public Shared Sub Main() Dim square1 As New Square(File.FileA, Rank.Rank1) Dim square2 As New Square(File.FileB, Rank.Rank1) Dim square3 As New Square(File.FileA, Rank.Rank1) Dim board As New Dictionary( Of Square, String) board.Add(square1, "R") board.Add(square2, "K") Console.WriteLine(board.Item(square1).ToString()) Console.WriteLine(board.Item(square2).ToString()) Console.WriteLine(board.Item(square3).ToString()) For Each element As KeyValuePair( Of Square, String) In board Console.WriteLine( "key : " & element.Key.ToString() & ", " & _ "value : " & element.Value) Next Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output R
K
R
key : FileA-Rank1, value : R
key : FileB-Rank1, value : K At compiletime wordt nu afgedwongen dat aan de Add method een Square en String argument wordt doorgegeven. Per ongeluk een value van ander type dan String doorgeven is nu niet meer mogelijk.
Een expressie als board.Item(square1) levert het element nu ook meteen in String vorm op. Castings zijn nu overbodig.
Bemerk dat bij het itereren over de elementen van de dictionary de elementen van type KeyValuePair(Of TKey, TValue), of hier specifiek van type KeyValuePair(Of Square, String) zijn. In dit geval elementen met een Key en Value property respectievelijk van de types Square en String.
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
|