|
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
Eén van de belangrijkste voordelen die genericiteit ons biedt is dat we niet meer genoodzaakt zijn om per elementtype een typesafe collectietype te creëren.
We weten ondertussen dat het voordelig is typesafe collections te gebruiken in tegenstelling tot de breedt inzetbare collectietypes die werken met elementen van het type Object.
Als we in een client zouden willen werken met zowel een listcollectie van Person, als van House elementen, dan kunnen we hiervoor twee typesafe listcollection definiëren. Visual Basic 2010 Broncode Option Strict OnOption Explicit OnNamespace Example1 Class Person Private m_Name As String Public Property Name() As String Get Name = m_Name End Get Set( ByVal value As String) m_Name = value End Set End Property End Class Class Persons : Inherits CollectionBase Public Sub Add( ByVal person As Person) List.Add(person) End Sub Default Public Property Item( ByVal index As Integer) As Person Get Item = DirectCast(List.Item(index), Person) End Get Set( ByVal value As Person) List.Item(index) = value End Set End Property End Class Class House Private m_Number As Integer Public Property Number() As Integer Get Number = m_Number End Get Set( ByVal value As Integer) m_Number = value End Set End Property End Class Class Houses : Inherits CollectionBase Public Sub Add( ByVal House As House) List.Add(House) End Sub Default Public Property Item( ByVal index As Integer) As House Get Item = DirectCast(List.Item(index), House) End Get Set( ByVal value As House) List.Item(index) = value End Set End Property End Class Class Client1 Public Shared Sub Main() Dim persons1 As New Persons persons1.Add( New Person With {.Name = "John"}) persons1.Add( New Person With {.Name = "Jane"}) For Each person As Person In persons1 Console.WriteLine(person.Name) Next Dim houses1 As New Houses houses1.Add( New House With {.Number = 21}) houses1.Add( New House With {.Number = 22}) For Each house As House In houses1 Console.WriteLine(house.Number) Next Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output John
Jane
21
22 Voor elke elementtype waarvoor een typesafe listcollectie gewenst is, moet een gelijkaardige constructie gecreëerd worden. De types Persons en Houses veschillen enkel in datatype van de elementen. Uiteindelijk dient men bij deze werkwijze quasi identieke code ( waar het enigste verschil het elementen datatype is ) te gaan herhalen. 23.1.1. Generieke KlassenOm van deze herhaling af te geraken, en de code dus bijvoorbeeld beter onderhoudbaar te maken, kan je opteren een "generieke" constructie voor deze typesafe listcollecties te definiëren.
Een generieke constructie maakt het mogelijk dezelfde functionaliteit toe te passen op verschillende datatypes. Indien je een generieke klasse of method definieert, hoef je geen aparte versie te maken voor elk datatype waarop dezelfde functionaliteit moet worden toegepast. Visual Basic 2010 Broncode Namespace Example1 Class GenericTypeSafeList( Of T) : Inherits CollectionBase Public Sub Add( ByVal value As T) List.Add(value) End Sub Default Public Property Item( ByVal index As Integer) As T Get Item = DirectCast(List.Item(index), T) End Get Set( ByVal value As T) List.Item(index) = value End Set End Property End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Bovenstaande generische klasse is geparameteriseerd met formeel parametertype T, men doet dit door na de identifier van de generieke klasse tussen haakjes (Of T) te plaatsen. Men kan van de identifier voor het parametertype afwijken, al gebruikt men hiervoor meestal T.
In plaats van nu tweemaal bijna identieke code te definiëren voor een typesafe listcollectie van zowel Person- als House elementen, gaat men specifiëren welke type als actuele generieke parameter wordt gebruikt : Visual Basic 2010 Broncode Namespace Example1 Class Client2 Public Shared Sub Main() Dim persons1 As New GenericTypeSafeList( Of Person) persons1.Add( New Person With {.Name = "John"}) persons1.Add( New Person With {.Name = "Jane"}) For Each person As Person In persons1 Console.WriteLine(person.Name) Next Dim houses1 As New GenericTypeSafeList( Of House) houses1.Add( New House With {.Number = 21}) houses1.Add( New House With {.Number = 22}) For Each house As House In houses1 Console.WriteLine(house.Number) Next Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output John
Jane
21
22 Naast klassen, kunnen ook structures, interfaces, delegates en zelfs methods generiek worden opgesteld. Bekijk de volgende topics voor meer details. boven
23.1.2. Generische InstantiesDe generieke klasse GenericTypeSafeList kan niet zomaar gebruikt worden om een instantie van te creëren. Dit type is immers niet compleet. We zullen eerst de formeel generische parameter ( T ) moeten invullen met een type ( Person en House ). Het invullen van de formeel generieke parameter gebeurt at compiletime en resulteert in een gewone ( niet generieke ) klasse ( men noemt dit ook wel de "generische instantie" ). At runtime wordt dan een object van die generische instantie ( die klasse ) gecreëerd.
Men kan meerdere typeparameters gebruiken in een generieke constructie (1). De identifiers van de typeparameters worden gescheiden door kommas in de Of clausule.
Als men een Shared member wenst aan te spreken van een generische instantie van een generieke klasse, doet men dit door de identifier van het type van die generische instantie aan te spreken (2). Visual Basic 2010 Broncode Namespace Example2 Class Container( Of T, U) Public Shared SharedField As T Public InstanceField As U End Class Class Client Public Shared Sub Main() Dim container1 As Container( Of Byte, Integer) = _ New Container( Of Byte, Integer) Container( Of Byte, Integer).SharedField = 1 container1.InstanceField = 2 Dim byte1 As Byte = Container( Of Byte, Integer).SharedField Dim integer1 As Integer = container1.InstanceField Console.WriteLine(byte1) Console.WriteLine(integer1) Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output 1
2 boven
23.1.3. System.Collections.ObjectModel.CollectionEen generieke klasse voor een typesafe listcollectie ( zoals in Example1 ) hoeven we niet eigenlijk niet zelf te definiëren. Er is reeds dergelijk generieke constructies voorgedefinieerd, namelijk System.Collections.ObjectModel.Collection en System.Collections.ObjectModel.ReadOnlyCollection. Visual Basic 2010 Broncode Namespace Example3 Public Class Client Public Shared Sub Main() Dim persons1 As New _ System.Collections.ObjectModel.Collection( Of Example1. Person) persons1.Add( New Example1. Person With {.Name = "John"}) persons1.Add( New Example1. Person With {.Name = "Jane"}) For Each person As Example1. Person In persons1 Console.WriteLine(person.Name) Next Dim houses1 As New _ System.Collections.ObjectModel.Collection( Of Example1. House) houses1.Add( New Example1. House With {.Number = 21}) houses1.Add( New Example1. House With {.Number = 22}) For Each house As Example1. House In houses1 Console.WriteLine(house.Number) Next Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output John
Jane
21
22
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
|