1. diel - Úvod do kolekcií a genericita
V dnešnej lekcii si povieme úvodnú teóriu ku kolekciám vo VB.NET, ktoré si v tomto kurze podrobnejšie rozoberieme.
Kolekcia
Pojem kolekcia označuje súbor dát, ktoré sú väčšinou
rovnakého typu a slúžia na špecifický účel. Počas
seriálu sme sa už stretli s dvoma typmi kolekciou, bolo to pole a
List
. Kolekcií existuje veľké množstvo a hoci sa zvonku
mnohokrát tvária podobne, vo vnútri fungujú veľmi odlišne a vyberáme si
ich podľa konkrétneho účelu. .NET disponuje veľkým množstvom
predpripravených kolekcií, s ktorými sa v tejto sekcii postupne zoznámime a
skúsime sa s nimi pracovať.
Generické a všeobecné kolekcie
Keď sa zamyslíme nad tým, ako by sme si urobili vlastnú kolekciu, určite
by sme po nejakej dobe dospeli k problému. Bol by ním dátový
typ kolekcie. Chceli by sme si napr. Naprogramovať vlastný
List
, vytvorili by sme triedu MujList.vb
, do nej
pridali príslušnej metódy a všetko potrebné. Pretože však chceme, aby
bola naša kolekcia univerzálne a vedela teda ukladať napr. Ako
Integer
, tak užívateľov, bude problém s dátovým typom prvkov
vnútri kolekcie. Existujú dva varianty, ako tento problém vyriešiť a aj
samotný .NET obsahuje kolekcie týchto dvoch typov.
Všeobecné kolekcia
Keďže vieme, že všetky dátové typy majú ako predka
triedu Object
, môžeme prvky v našej kolekcii ukladať práve do
tohto dátového typu. Do kolekcie teraz môžeme uložiť v podstate
čokoľvek. Nevýhodou je, že sama kolekcia skutočný dátový typ prvkov
nepozná a preto vie prvky navracať len ako všeobecné objekty. Po získaní
prvku z kolekcie si ho teda musíme pretypovať.
Uveďme si príklad negenerické kolekcie, je jej ArrayList
:
using System.Collections;
{VBNET_CONSOLE}
Dim list As New ArrayList()
list.Add("položka")
Dim polozka As String = CType(list(0), String)
Console.WriteLine(polozka)
{/VBNET_CONSOLE}
Výstup programu:
Konzolová aplikácia
položka
Po vytvorení listu si doň pridáme položku typu String
. Aby
sme túto položku mohli z Listu získať späť, treba ju na
String
spätne pretypovať.
Pre funkčnosť kódu musíme pridať
Imports System.Collections
. Keďže tento menný priestor nie je v
predvolenom projektu prítomný, napovedá nám to, že negenerické kolekcia
nebudú tá obvyklá voľba.
Generické kolekcia
Generické kolekcia rieši problém s dátovým typom na úrovni jazyka
VB.NET. Zavádza tzv. Genericitu. Zjednodušene povedané sa
jedná o možnosť špecifikovať typ údajov až vo chvíli
vytvorenie inštancie. V triede samotnej kolekcie sa potom
pracuje s generickým typom, ktorý slúži ako zástupca pre
budúce dátový typ. Môžeme si to predstaviť tak, že sa
generický typ v triede zmení napr. Na String
vo chvíli, keď
vytvoríme jej inštanciu. Jedná sa teda o možnosť triedy nejakým spôsobom
parametrizovať.
Generický List
už poznáme a onen dátový typ (parameter) sa
generickým triedam špecifikuje v zátvorkách uvádzaný slovom
Of
. Máme možnosť špecifikovať dátový typ iba
raz, pri vytvorení kolekcie. Akékoľvek
ďalšie pretypovanie odpadá:
{VBNET_CONSOLE}
Dim list As New List(Of String)()
list.Add("položka")
Dim polozka As String = list(0)
Console.WriteLine(polozka)
{/VBNET_CONSOLE}
Výstup programu:
Konzolová aplikácia
položka
Program funguje úplne rovnako, ako ten s negenerické kolekciou
ArrayList
, však čítať môžeme bez nepohodlného
pretypovanie.
Generické kolekcia nahradili kolekcia všeobecné a tie sa už príliš nepoužívajú. V kurze sa budeme venovať generickým kolekciám a ich negenerické verzie len zmienime.
Genericita
Genericita je samozrejme vlastnosť jazyka VB.NET a my ju máme možnosť vo svojich triedach používať.
Zatiaľ sa nebudeme zaťažovať tvorbou vlastnej kolekcie. Vytvorme si
triedu, ktorá bude jednoducho spravovať jednu premennú. Premenná bude
generická, teda ľubovoľného dátového typu. Založíme si nový projekt,
konzolovú aplikáciu s názvom Genericita
. Pridáme si novú
triedu, pomenujte ju teraz pre študijné účely iba Trida
. V jej
deklarácii pridáme generický parameter, ktorý pomenujeme T
:
Public Class Trida(Of T) End Class
Generických parametrov môžeme zadať v zátvorke po Of
viac,
oddelíme ich čiarkou. Niekedy sa to môže hodiť, my sa s tým stretneme
ďalej u generických slovníkov.
Presunieme sa do metódy Main()
, kde si vytvoríme inštanciu
našej triedy:
Dim instance As New Trida(Of Integer)(10)
Nezabudneme na okrúhle zátvorky a Of
ako u dátového
typu, tak u konstruktoru. Teraz sme parametra
T
v tejto inštanciu triedy určili dátový typ
Integer
. Rovnako tak si môžeme urobiť ďalší inštanciu tej
istej triedy a parametra T
dať úplne iný dátový typ, napr.
S
. Stačí nám teda jedna trieda pre viac
dátových typov.
Pokračujme a vytvorme si v triede atribút. T
môžeme použiť
ako bežný dátový typ:
Private promenna As T
Triede ešte dodáme konštruktor, ktorý premennú inicializuje:
Public Sub New(promenna As T) Me.promenna = promenna End Sub
V Main()
aktualizujeme vytvorení inštancie:
Dim instance As New Trida(Of Integer)(10)
Teraz inštancie obsahuje atribút promenna
, ktorý je typu
Integer
a nadobúda hodnoty 10
.
Môžeme dokonca pridať metódu, ktorá bude mať naviac ďalšie generický parameter (iný, než má trieda). Mohla by vyzerať napr. Nasledovne:
Public Function Porovnej(Of T2)(a As T2) As Boolean Return promenna.Equals(a) End Function
Skúsime si teda porovnať náš Integer
s nejakým iným
typom:
{VBNET_CONSOLE} Dim instance As New Trida(Of Integer)(10) Dim stejne As Boolean = instance.Porovnej(Of String)("15") Console.WriteLine(stejne) {/VBNET_CONSOLE}
{VBNET_OOP} Public Class Trida(Of T As {IComparable, New}) Private promenna As T Public Sub New(promenna As T) Me.promenna = promenna End Sub Public Function Porovnej(Of T2)(a As T2) As Boolean Return promenna.Equals(a) End Function End Class {/VBNET_OOP}
Výstup programu:
False
Ďalšie konštrukcie
Pre úplnosť si ešte uveďme niekoľko konštrukcií.
Generický parameter triedy je možné bližšie
špecifikovať, presnejšie obmedziť. Slúži na to zložené zátvorky
nasledujúce za As
. Môžeme tak nastaviť, že udaný dátový typ
musí napr. Obsahovať rozhranie IComparable
:
Public Class Trida(Of T As {IComparable}) End Class
Vďaka tomu môžeme na premenných typu T
teraz vnútri triedy
volať metódy z daného rozhrania. Samotné rozhranie môže
opäť obsahovať generický parameter, aby sme generické typy
mohli používať aj v hlavičkách jeho metód.
Keď uvedieme New
, môžeme vnútri typ T
instanciovat. Taká malá továreň na inštancie ľubovoľného typu by mohla
vyzerať takto:
Public Class Tovarna(Of T As New) Public Function VytvorInstanci() As T Return New T() End Function End Class
Ak máme vo {}
už nejaká rozhranie,
New
dáme jednoducho medzi ne a oddelíme čiarkou.
Nakoniec si ukážme, ako môžeme typ parametra obmedziť z hľadiska dedičnosti:
Public Class Trida(Of A As B, B As C, C) End Class
Vyššie sme deklarovali triedu s tromi generickými parametrami, kde
A
je potomkom B
a B
je potomkom
C
.
V budúcej lekcii, Zoznam (List) pomocou poľa vo VB.NET , sa pozrieme na listy, predstavíme si rôzne implementácie tejto kolekcie a ich výhody a nevýhody.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 9x (256.43 kB)
Aplikácia je vrátane zdrojových kódov v jazyku VB