Programujeme ve Visual Basic .NET - 12. díl - základní jmenné prostory .NET

Dnes si představíme funkcionalitu tříd, nabízenou v základních jmenných prostorech .NET.

Naprostá většina tříd a funkcí knihoven .NET Framework je shromážděna ve dvou výchozích jmenných prostorech: System a Microsoft. Zatímco jmenný prostor System obsahuje třídy, které jsou předmětem základní ECMA specifikace Common Language Runtime (CLI) jakožto systémově i jazykově nezávislé platformy, jmenný prostor Microsoft obsahuje specifické implementace systému Windows (jako jsou např. funkce pro práci se registry) a jazyků .NET jako např. Visual Basic a jeho specifické funkce - nelze tedy předpokládat v dohledné době portování jmenného prostoru Microsoft na další platformy, jako je např. Rotor (Shared Source .NET), Mono nebo DotGNU. Protože pro návrh aplikací je dobrá alespoň povšechná orientace o funkčnosti .NET, kterou tato platfroma nabízí, v tomto přehledu se s ní stručně seznámíme.

Jmenný prostor System

Jmenný prostor System zahrnuje především deklarace všech základních datových typů a V předchozí části jsme se seznámili s třídami .NET a předvedli rozdíly, kterými se liší od modulů a struktur VB.NET. Další významný rozdíl v použítí tříd oproti modulům je, že jejich deklarace mohou být vzájemně libovolně vnořovány, např.:

Class Teleso
  . . . .
  Class Plocha
    . . . 
     Class Hrana
       . . . 
     End Class
  End Class
End Class

Na jednoltlivé úrovně vnořených tříd a jejich členy se pak můžeme odkazovat tečkovou syntaxí podobně, jako jsme to již prováděli voláním metody System.Console.WriteLine(), např.

Teleso.Plocha.Hrana...

Knihovny .NET obsahují několik tisíc tříd, které pokrývají většinu infrastruktury operačního systému. To je nesrovnatelně větší rozsah funkcionality, než kterým disponovaly např. první verze BASICu, které využívaly jen několik stovek pevně vestavěných funkcí a klíčových slov a navíc jej lze libovolně dále rozšiřovat připojováním dalších komponent. Orientaci v tak velkém počtu deklarací výrazně zjednodušuje hiearchická struktura prostředí .NET Framework.

Jmenné prostory (obory názvů) .NET

Pro zpřehlednění .NET Framework zavádí tzv. jmenné prostory, nebo-li obory názvů - v angličtině "namespaces " (občas se můžeme setkat i s označením "názvové prostory"), které hrají ve struktuře tříd podobnou úlohu, jako adresáře v souborového systému: samy o sobě neobsahují žádná data, ale vymezují jejich hierachickou strukturu.

Namespace Rovina
  Class Ctverec
  End Class
End Namespace
Namespace Prostor
  Class Ctverec
  End Class
  Namespace Telesa
    Class Krychle
    End Class
    Class Hranol
    End Class
  End Namespace
End Namespace

Jmenné prostory se v kódu definují blokem příkazů Namespace - End Namespace a při volání vymezují plnou cestu ke třídě, nebo proměnné podobně jako cestu k souboru (s tím rozdílem, že se jako oddělovač nepoužívá zpětné lomítko, ale opět tečka. Stejně jako soubory adresářů, jmenné prostory umožňují využívat třídy, které mají shodné názvy tím, že jsou umístěny v různých jmenných prostorech:

Rovina.Ctverec...
Prostor.Ctverec..

Ačkoliv většina základních jmenných prostorů .NET má vyhraženu samostatnou knihovnu DLL (obvykle odpovídajícího jména v adresáři %SystemRoot%\Microsoft.NET), jmenné prostory umožňují sloučit třídy, které jsou fyzicky umístěny v různě umístěných komponentách, dokonce i rozdílného původu, protože stačí, pokud tyto knihovny obsahují deklarace jmenných prostory shodného jména. To umožňuje používat třídy z několika různých komponent, dodaných programátory ve vývojářské společnosti tak, jako kdyby byly implementovány v jediné knihovně - členění tříd do jmenných prostorů tedy prochází napříč komponentami.Na webu research.microsoft.com je k dispozici utilita ILMerge, která na tomto základě umožňuje několik knihoven spojit do jediného souboru, což může například zjednodušit distribuci aplikace složené z většího počtu komponent.

Jmenné prostory (obory názvů) .NET vymezují hiearchickou strukturu tříd podobně jako adresáře (složky) udržují strukturu souborů

Vzhledem k tomu, že velký počet tříd na jednom místě  (stejně jako velký počet souborů v adresáři) zhoršuje orientaci a navigaci v nabídkách vývojového prostředí, je vhodné zavést a využívat jmenné prostory v každém větším projektu. V praxi je například zvykem všechny třídy vyvinuté v jedné firmě deklarovat ve jmenném prostoru s názvem, odpovídajícím názvu společnosti, čímž se zabrání případné kolizi s názvy tříd v komponentách jiných výrobců, popř. s názvy tříd v samotném prostředí .NET Framwork.

Příkaz Imports

Používání jmenných prostorů sice vnáší do světa komponent přehled a řád, na druhé straně je spojeno s nutností názvy jmenných prostorů v kódu vypisovat, podobně jako je nutné v příkazové řádce vypisovat úplnou cestu k souboru v adresářové struktuře. Na tuto skutečnost jsme již narazili v ukázkách v předchozích dílech seriálu, kde byla opakovaně uváděna kompletní cesta k rozhraní System.Console.WriteLine() nebo System.Console.ReadLine(). Naštěstí nás .NET tuto povinnost usnadňuje zavedením příkazu Imports, který funguje podobně jako příkaz (resp. systémová proměnná) PATH v souborovém systému. Překladač před spuštěním kódu prochází názvy jmenných prostorů vyjmenovaných příkazem Imports a k těm názvům tříd, popř. členů jejich rozhraní které v kódu nalezne příslušnou cestu jmenných prostorů připojí automaticky, takže např. namísto:

Module modMain
  Sub Main
    Dim a = System.Console.ReadLine()
    System.Console.WriteLine(a)
  End Sub
End Module

stačí zkráceně zapsat s využitím příkazu Imports:

Imports System
Module modMain
  Sub Main
    Dim a = Console.ReadLine()
    Console.WriteLine(a)
  End Sub
End Module

popřípadě ještě stručněji:

Imports System.Console
Module modMain
  Sub Main
    Dim a = ReadLine()
    WriteLine(a)
  End Sub
End Module

Příkaz Imports lze v každém zdrojovém kódu použít výhradně na začátku souboru. Je zde však možné uvést  příkazů Imports více, popř. jedním příkazem Imports vyjmenovat několik jmenných prostorů současně, např. tato kombinace:

Imports System, System.Console

odpovídá dvojicí příkazů :

Imports System
Imports System.Console

Kolize názvů

Ačkoliv nám rozumné používání příkazů Imports může ušetřit hodně času při psaní zdrojového kódu, je nutné mít na paměti, že tím může dojít ke kolizi názvů tříd nebo jejich členů z různých jmenných prostorů - např. pokus o překlad a spuštění níže uvedené ukázky selže v důsledku kolize názvů tříd Convert obsažené ve dvou jmenných prostorech současně a překladač oznámí chybu "Název Convert je dvojznačný a je importován z oboru názvů nebo typů System.Text.Encoding, System."

Imports System, System.Text.Encoding
Module modMain
  Sub Main
    Console.Write(Convert.ToChar(7))
  End Sub
End Module

Danou chybu opravíme jednoduše tak, že při volání metody Convert() doplníme plnou cestou k příslušnému jmennému prostoru, čímž se zápis stane jednoznačný:

Imports System, System.Text.Encoding
Module modMain
  Sub Main
    Console.Write(System.Convert.ToChar(7))
  End Sub
End Module

Čas od času se také může stát, že  po zavedení jmenného prostoru příkazem Imports() název nějaké proměnné, kterou jsme si v kódu deklarovali koliduje s názvem nějaké třídy nebo jejího rozhraní, popř. samotným klíčovým slovem jazyka VB.NET. Situace je dále komplikována tím, že VB.NET nerozlišuje mezi velkými a malými písmeny v názvech tříd a proměnných (tzv. case insensitive syntaxe). Ačkoliv takový přístup nelze obecně doporučit, prostředí VB.NET je benevolentní do té míry, že mu lze takový název vnutit tak, že jej uzavřeme do hranatých závorek, například:

Module modMain
  Sub Main
    Dim [Dim] = "Hello"
    System.Console.Write([Dim])
  End Sub
End Module

Zástupná jména

V některých případech může dojít k tomu, že potřebujeme využít komponentu třetí strany, využívající shodou náhod stejné jmenné prostory, jaké jsme se rozhodli používat sami. Někdy nám také označení názvových prostorů nemusí vyhovovat a rádi bychom je přizpůsobili svým zvyklostem (např. zkrátili) apod. Pro tyto případy příkaz Imports podporuje přiřazení zástupného jména (přezdívky, tzv. alias)  jmenného prostoru, kterým lze daný obor názvů přejmenovat. Např. při pokusu o přeložení a spuštění níže uvedené ukázky nám překladač oznámí chybu "Název Ctverec je dvojznačný a je importován z oboru názvů nebo typů Prostor, Rovina."

Imports Rovina, Prostor
Module modMain
  Sub Main
    Dim C As Ctverec    ` chyba, kolize názvů !
  End Sub
End Module
Namespace Rovina
  Class Ctverec
  End Class 
End Namespace
Namespace Prostor
  Class Ctverec
  End Class 
End Namespace

Problém můžeme vyřešit uvedením úplného názvu třídy v daném oboru názvů (Rovina.Cverec nebo Prostor.Ctverec), nebo substitucí jmenného prostoru názvem příslušné třídy. Název Ctverec3D je v tomto případě aliasem názvu třídy Prostor.Ctverec:

Imports Rovina, Ctverec3D = Prostor.Ctverec
Module modMain
  Sub Main
    Dim C As Ctverec3D
  End Sub
End Module
. . . . .

Stručné shrnutí

Seznámili jsme se deklarací a použitím jmenných prostorů, příkazem Imports a na několika ukázkách jsme demonstrovali některé přístupy k řešení kolize názvů v jmenných prostorech .NET. Jmenné prostory a příkaz Imports mají v hiearchické struktuře tříd podobnou funkci a význam, jako adresáře a příkaz PATH v adresářové struktuře souborového systému.

V následujícím dílu se porozhlédneme po základních názvových prostorech knihoven .NET a seznámíme se s funkcemi, které pro naše účely zapouzdřují.

Diskuze (11) Další článek: Soubory: Zdarma česko-anglický slovník Verdict!

Témata článku: , , , , , , , , , , , , , , , , , , , , , , , , ,