NULOVATELNÉ TYPY POD LUPOU

Podobné dokumenty
Algoritmizace a programování

Úvod do programovacích jazyků (Java)

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

5 Přehled operátorů, příkazy, přetypování

PŘETĚŽOVÁNÍ OPERÁTORŮ

přetížení operátorů (o)

Paměť počítače. alg2 1

Základy jazyka C# Obsah přednášky. Architektura.NET Historie Vlastnosti jazyka C# Datové typy Příkazy Prostory jmen Třídy, rozhraní

Programování v C++, 2. cvičení

Úvod do programovacích jazyků (Java)

4. blok část A Logické operátory

Zápis programu v jazyce C#

Programovací jazyk Pascal

Datové typy strana 29

DATOVÉ TYPY POKRAČOVÁNÍ

Operátory, výrazy. Tomáš Pitner, upravil Marek Šabo

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Základy programování (IZP)

Pokročilé programování v jazyce C pro chemiky (C3220) Pokročilá témata jazyka C++

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

Algoritmizace a programování

7. Datové typy v Javě

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

V dalších letech se pak začaly objevovat první normy pro jazyk C++ (ISO/IEC 14882:1998; ISO/IEC 9899:1999; ISO/IEC 14882:2003; ISO/IEC 14882:2011).

Jak v Javě primitivní datové typy a jejich reprezentace. BD6B36PJV 002 Fakulta elektrotechnická České vysoké učení technické

Algoritmizace prostorových úloh

8 Třídy, objekty, metody, předávání argumentů metod

DUM 07 téma: Proměnné, konstanty a pohyb po buňkách ve VBA

Výrazy, operace, příkazy

PB161 Programování v jazyce C++ Přednáška 4

Jazyk C++, některá rozšíření oproti C

Pointery II. Jan Hnilica Počítačové modelování 17

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Programovací jazyk C++ Hodina 1

MAXScript výukový kurz

1.1 Struktura programu v Pascalu Vstup a výstup Operátory a některé matematické funkce 5

Programování v jazyce C a C++

Jazyk PL/SQL Úvod, blok

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Booleovská algebra. Booleovské binární a unární funkce. Základní zákony.

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

MATURITNÍ OTÁZKY ELEKTROTECHNIKA - POČÍTAČOVÉ SYSTÉMY 2003/2004 PROGRAMOVÉ VYBAVENÍ POČÍTAČŮ

Úvod do programování. Lekce 1

Úvod do databázových systémů

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

Třídy a struktury v C++

Jazyk SQL 1. Michal Valenta. Katedra softwarového inženýrství FIT České vysoké učení technické v Praze c Michal Valenta, 2012 BI-DBS, ZS 2011/12

Úvod do databázových systémů

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

02. HODINA. 2.1 Typy souborů a objektů. 2.2 Ovládací prvky Label a TextBox

Algoritmizace a programování

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

Algoritmizace prostorových úloh

O datových typech a jejich kontrole

Informační systémy 2008/2009. Radim Farana. Obsah. Dotazy přes více tabulek

Programování v jazyce JavaScript

Generické programování

PB161 Programování v jazyce C++ Přednáška 9

ZPRO v "C" Ing. Vít Hanousek. verze 0.3

PROGRAMOVÁNÍ V JAZYCE C V PŘÍKLADECH 11 Dynamické datové struktury 11.1 Spojové struktury Příklad PROG_

Strukturu lze funkci předat: (pole[i])+j. switch(výraz) velikost ukazatele

6 Příkazy řízení toku

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

Databázové systémy Cvičení 5.2

Inovace a zkvalitnění výuky prostřednictvím ICT Základy programování a algoritmizace úloh. Ing. Hodál Jaroslav, Ph.D. VY_32_INOVACE_25 09

9. přednáška - třídy, objekty

6. blok část C Množinové operátory

Programování v jazyce JavaScript

Databáze I. Přednáška 4

6. Příkazy a řídící struktury v Javě

Registrační číslo projektu: CZ.1.07/1.5.00/ Elektronická podpora zkvalitnění výuky CZ.1.07 Vzděláním pro konkurenceschopnost

Sada 1 - PHP. 03. Proměnné, konstanty

typová konverze typová inference

Racionální čísla, operátory, výrazy, knihovní funkce

Ukazatele a pole. Chceme-li vyplnit celé pole nulami, použijeme prázdný inicializátor: 207 Čárka na konci seznamu inicializátorů

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

MQL4 COURSE. V tomto dodatku je obsažen popis 25 obchodních funkcí jazyka MQL4. Rozhodl jsem se napsat

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Databázové systémy. * relační kalkuly. Tomáš Skopal. - relační model

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

Úvod do databázových systémů

Binární logika Osnova kurzu

Operátory. Základy programování 1 Martin Kauer (Tomáš Kühr)

Racionální čísla, operátory, výrazy, knihovní funkce

Výčtový typ strana 67

Základní datové struktury

Odvozené a strukturované typy dat

přetížení operátorů (o)

C++ Akademie SH. 2. Prom nné, podmínky, cykly, funkce, rekurze, operátory. Michal Kvasni ka. 20. b ezna Za áte níci C++

Výroková logika - opakování

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Databázové systémy. - SQL * definice dat * aktualizace * pohledy. Tomáš Skopal

Program převod z desítkové na dvojkovou soustavu: /* Prevod desitkove na binarni */ #include <stdio.h>

InterSystems Caché Post-Relational Database

Přetěžování operátorů

PREPROCESOR POKRAČOVÁNÍ

Transkript:

NULOVATELNÉ TYPY POD LUPOU Aleš Keprt Katedra informatiky, FEI, VŠB Technická Univerzita Ostrava 17.listopadu 15, 708 00 Ostrava Poruba Aley@Keprt.cz Abstrakt Nová verze jazyka C# od Microsoftu obsahuje mimo jiné nový programovací prvek zvaný nulovatelné typy. Toto rozšíření umožňuje přiřazovat null do proměnných všech hodnotových typů a je vhodné zejména pro pohodlnou práci s SQL a relačními databázemi. Implementace nulovatelných typů v jazyce C# však skrývá řadu na první pohled ne zcela zřejmých vlastností. Jedná se zejména princip vazby na běžné hodnotové typy formou lifted conversions a zpracování operátorů formou lifted operators. Tyto neobvyklé konstrukce vycházejí ze snahy obejít některá nepříjemná omezení ohledně využívání operátorů v jazyce C#. Příspěvek je zaměřen na podrobný popis této problematiky. 1 Úvod Hodnotové typy (nullable types) jsou jednou z novinek, která se v jazyce C# objevuje v nové verzi 2.0. Pravděpodobně již konečná specifikace tohoto jazyka byla představena v květnu roku 2004 [1], zatímco nové Visual Studio 2005 je v době psaní tohoto textu teprve těsně před zveřejněním verze beta 2, která by se měla objevit koncem března. Tento příspěvek představuje nulovatelné typy ve dvou fázích. V první části jsou srozumitelně představeny běžné konstrukce, s vynecháním detailů, které by mohly ztížit pochopení. Podobné informace je možné najít také v MSDN verze 2005 [9], článku [3] nebo seriálu [2]. Druhá část příspěvku odkrývá další detaily nulovatelných typů, které v běžné literatuře nenajdeme. V závěru jsou ještě zmíněny některé myšlenky a teze, které jsou důsledkem diskuzí odborné veřejnosti nad nulovatelnými typy. 2 Nulovatelné typy 2.1 Úvod Jak známo, hodnotové datové typy (všechny typy struct, dále int, char, double, apod.) nepoužívají reference, nelze jim proto přiřadit null. Většinou to nemá žádný negativní dopad, někdy by však taková nepřiřazená reference mohla být využita k nějakým speciálním účelům. Například při práci s relačními databázemi se použití null přímo nabízí pro reprezentaci neuvedených (tj. prázdných) hodnot v datech načtených z databáze do C#. Chceme-li však mít takovou neuvedenou hodnotu například u datového typu int, pak nezbývá, než jako neuvedenou hodnotu použít některé z čísel, které nepotřebujeme. Může to být třeba 1, ale v případě, že daná proměnná může nabývat všech hodnot z domény příslušného datového typu, nastává obtížný problém. Používání vybraných čísel místo null navíc komplikuje kód a často vede k celé řadě (lidských) chyb. Nyní máme v jazyce C# k dispozici tzv. nulovatelné typy. Jsou to hodnotové typy, kterým ovšem můžeme přiřadit i hodnotu null. Každý nulovatelný typ je postaven nad nějakým

(libovolným) již existujícím hodnotovým typem (označujeme jej potom jako typ bázový nemá to však nic společného s dědičností) a přidává do jeho domény null. Nulovatelnou proměnnou (tj. proměnnou nulovatelného typu) deklarujeme uvedením bázového typu a přidáme otazník. Jak ukazuje následující příklad, i základní použití nulovatelných proměnných je zcela intuitivní. int? x; Console.WriteLine(x==null? "null" : x.value.tostring()); if(x.hasvalue) Console.WriteLine("x má hodnotu"); Nulovatelné typy mají tyto vlastnosti: Jsou vhodné pro proměnné, které mohou obsahovat nedefinovanou hodnotu. Syntaxe T? pouze zastupuje delší zápis System.Nullable<T>. Zápis s otazníkem je tedy ekvivalentní zápisu přes generický typ, vysvětlení generických typů je možno nalézt v [2], [3], [9]. Vlastnost HasValue slouží ke zjištění, zda má daná proměnná hodnotu (pak vrací true), nebo je null (pak vrací false). Vlastnost Value zpřístupňuje hodnotu typu T. Přiřazení hodnoty default způsobí nastavení HasValue = false. (Slovo default je jednou z dalších novinek jazyka C# vysvětlení viz [2], [3], [9].) 2.2 Přetypování Přetypování z nulovatelného T? na jeho bázový typ (T) je možný explicitním přetypováním, převod z bázového typu je dokonce implicitní. int a; int? x; x = a; //implicitní přetypování int int? a = (int)x; //explicitní přetypování int? int //vyvolá výjimku, když x bude null 2.3 Operátory Nulovatelné typy mají všechny operátory stejné jako bázový typ. Výsledkem operací, do kterých vstupuje null hodnota, je vždy null hodnota. Chování operátorů je tedy zcela intuitivní, uvedeme jen několik příkladů. double? a,b; long? c; a = b * 2.0; c++; if(a > c) {...} Pro pohodlnou práci můžeme použít také nově zavedený operátor?? (dva otazníky), který umožňuje definovat výchozí hodnotu při přetypování na bázový typ.

int? x; int y = x?? -1; V této ukázce do proměnné y přiřazujeme hodnotu proměnné x. Pokud by x bylo null, pak je do y přiřazena hodnota 1. Operátor?? můžeme použít i pro přiřazování mezi nulovatelnými proměnnými. int? z = x?? -1; Přestože z je nulovatelná proměnná, tímto příkazem do ní vložíme vždy nenulovou (not null) hodnotu. (Operátor?? totiž převede hodnotu na bázový typ int, při následném přiřazení do int? je pak použit implicitní konverzní operátor.) Když naopak chceme do nulovatelné proměnné vložit null, jednoduše jí přiřadíme literál null. z = null; 3 Další detaily, aneb nulovatelné typy pod lupou 3.1 Přístup k vlastnostem Value a HasValue Vlastnosti (properties) Value a HasValue jsou jen ke čtení, nelze jim tedy přiřadit hodnotu. Chceme-li změnit hodnotu Value, použijeme přiřazení přímo do proměnné. int? a; a.value = 20; //chyba Value je jen ke čtení a = 20; //toto je správně Chceme-li přiřadit hodnotu false do HasValue, uděláme to přiřazením null do proměnné. a.hasvalue = false; //chyba HasValue je jen ke čtení a = null; //toto je správně Hodnotu true do HasValue samozřejmě přiřadíme jedině tak, že přímo přiřadíme nějakou konkrétní hodnotu do proměnné (tj. jinou než null). 3.1 Typové konverze Princip generického programování zavedený v jazyce C# není dostatečně flexibilní, aby uměl popsat obecné typové konverze nulovatelných typů; tyto konverze tedy mají v jazyce zvláštní postavení. Obecně platí pravidlo, že nulovatelný typ poskytuje všechny typové konverze, které má jeho bázový typ. Navíc je možno kombinovat při převodech libovolné bázové i nulovatelné typy, pokud existují příslušné konverzní operátory pro příslušné bázové typy. Platnost tohoto pravidla je zřejmá již z sekce 2.2, při konverzích se totiž využívají výše zmíněné implicitní a explicitní konverze mezi nulovatelným typem a jeho bázovým typem. V následujících odstavcích si popíšeme všechny možné situace. (Poznámka: Těmto konverzím se v originální anglické specifikaci jazyka [1] říká lifted conversions, čili česky vyzvednuté nebo pozvednuté konverze.)

3.1.1 Převod z hodnotového (nenulovatelného) na nulovatelný typ Převod z hodnotového (nenulovatelného) na nulovatelný typ probíhá s využitím implicitní konverze z bázového typu na jeho nulovatelný typ. Tato konverze je tedy také implicitní, pokud je konverze mezi bázovými typy implicitní, jinak je explicitní. int? a = 'A'; //implicitní konverze char int? char? b = (char?)65; //explicitní konverze int char? char? b = (char)65; //explicitní konverze int char //potom implicitní char char? 3.1.2 Převod z nulovatelného typu na nulovatelný typ Převod z nulovatelného typu na (jiný) nulovatelný typ probíhá tak, že hodnota null je zachována a pro ostatní hodnoty je použit příslušný konverzní operátor bázového typu. Tato konverze je tedy implicitní, pokud je konverze mezi bázovými typy implicitní, jinak je explicitní. int? a = (char?)'a'; //implicitní konverze char? int? char? b = (char?)(int?)65; //explicitní konverze int? char? 3.1.3 Převod z nulovatelného typu na hodnotový typ Převod z nulovatelného typu na (jiný než jeho vlastní bázový) hodnotový typ vyvolá výjimku v případě, že výchozí hodnota je null. V ostatních případech je použita explicitní konverze na bázový typ a potom příslušný konverzní operátor bázového typu. Tato konverze je tedy vždy explicitní (tj. je třeba toto přetypování vždy explicitně uvést, není nikdy provedeno automaticky). Je-li konverzní operátor bázového typu explicitní, dochází tak de facto ke dvojí explicitní konverzi. Překladač však tuto konverzi považuje za přímou explicitní konverzi první řádek z následujícího příkladu tak ukazuje zbytečně složitou dvojí konverzi. char a = (char)(int)(int?)65; //explicitní konverze int? int //potom druhá explicitní int char char a = (char)(int?)65; //přímá explicitní konverze int? char 3.2 Jak fungují operátory Stejně jako přetypování, i operátory jsou nulovatelným typům zavedeny pomocí explicitní a implicitní konverze mezi nulovatelným a jeho bázovým typem (viz sekci 2.2). (Specifikace jazyka [1] pak hovoří o lifted operators, čili česky o vyzvednutých nebo pozvednutých operátorech.) 3.2.1 Unární operace s nulovatelným typem Definuje-li bázový typ nějaký unární operátor, pak nulovatelný typ nad ním má tento operátor také. Je-li vstupní hodnotou null, pak výsledkem je také null. V opačném případě je hodnota konvertována na bázový typ, na něm je provedena operace a výsledek je konvertován zpět na nulovatelný typ. Výsledkem je pak tedy nenulová hodnota nulovatelného typu.

(Paradoxně se zde tedy objevuje implicitní použití explicitní konverze na bázový typ je to však bezpečné, neboť k tomu dojde jen při nenulové hodnotě vstupu.) int? a = 20; a++; //pozvednutý unární operátor ++ 3.2.2 Binární operace s nulovatelným typem Binární operace mají dvě vstupní hodnoty, může zde tedy nastat více situací. Je-li alespoň jedna ze vstupních hodnot null, potom výsledkem operace je také null. Není-li ani jedna ze vstupních hodnot null, pak jsou obě přetypovány na své bázové typy a je použit příslušný operátor bázového typu. Výsledek je pak převeden na příslušný nulovatelný typ. (Opět je zde tedy implicitní použití explicitní typové konverze a opět je bezpečné.) 3.2.3 Test na null Jak již bylo řečeno, test na null provádíme pomocí vlastnosti HasValue. Můžeme k tomu však použít i speciální tvar operátorů == a!=, jak ukazuje následující příklad. int? a; if(a.hasvalue==false) { /* je to null */ } if(a==null) { /* je to null */ } Obě tyto konstrukce jsou ekvivalentní, ta druhá je zřejmě více intuitivní. 3.3 Trojhodnotový typ bool? Specifické postavení mezi nulovatelnými typy má bool?. Jak ukazuje tabulka 1, operátory logického součtu a logického součinu & dávají u tohoto typu v některých případech nenulové výsledky, i když jeden z operandů je null. Toto chování odpovídá klasické (matematické) trojstavové logice, potažmo chování trojstavové logiky v jazyce SQL a je specifické právě pro typ bool? u všech ostatních nulovatelných typů platí, že výsledkem binárních operací, kde jeden (nebo i oba) operandy jsou null, je vždy hodnota null. Tabulka 1. Tabulka pravdivostních hodnot typu bool? pro operátory & a. & (and) null false true (or) null false true null null false null null null null true false false false false false null false true true null false true true true true true 3.4 Nulovatelné typy vyšších řádů Přímo z definice nulovatelných typů (viz 2.1) je zřejmé, že každý nulovatelný typ je sám také typem hodnotovým a tudíž může být použit jako bázový typ pro další nulovatelný typ. V praxi to znamená, že C# umožňuje tzv. zřetězení otazníků, jak ukazuje další příklad. int?? a = null;

Tato konstrukce tedy vytvoří nulovatelnou proměnnou typu int??, což je nulovatelný typ nad bázovým typem int? (a int? je nulovatelný typ nad int). Tato konstrukce nápadně připomíná ukazatele vyšších řádů a principiálně také funguje obdobně. 1 unsafe { int** p = null; } Jeden zásadní rozdíl oproti ukazatelům vyšších řádů tu však je a týká se právě přiřazování null použitém ve výše uvedených příkladech. U ukazatelů se totiž rozlišuje ukazatel roven null a ukazatel ukazující na proměnnou rovnou null. U nulovatelných typů se však nulovatelná proměnná s hodnotou null a nulovatelná proměnná s hodnotou nulovatelného typu, jejíž hodnota je null nerozlišuje. Tento rozdíl je možno vyzkoušet například takto. //toto vypíše true unsafe { int* p1 = null; int** p2 = &p1; System.Console.WriteLine("p2 má hodnotu? {0}", p2!=null); } //toto vypíše false int? v1 = null; int?? v2 = v1; System.Console.WriteLine("v2 má hodnotu? {0}", v2.hasvalue); Přestože na předposledním řádku přiřazujeme nějakou hodnotu typu int?, což jistě není totéž jako přiřazovat literál null, proměnná v2 se nastaví na hodnotu null. 4 Další myšlenky Nad nulovatelnými typy se strhla bouřlivá diskuze na internetu. Na jedné straně totiž zjednodušují kód, zejména práci s relačními databázemi, na druhé straně však přinášejí několik sporných bodů: 1. Jednoduchá deklarace ve tvaru int? se každému nemusí nelíbí. Především kvůli tomu, že jde jen o syntaktický cukr, se programátoři rozdělili na dva proti sobě stojící tábory. Zástupci prvního tábora preferují jazyk C a odvozené jazyky pro jejich stručný zápis mnoha konstrukcí (viz operátor?:), druhý tábor to naopak považuje za zbytečné zkracování deklarací a prvek znepřehledňující kód. 2. Nulovatelné typy můžeme chápat také jako předkrok k zavedení podpory proměnných ve formě jednoduchých regulárních výrazů. Výraz int? totiž můžeme chápat jako žádný nebo jeden int. Potom int! by odpovídalo int a znamenalo by právě jeden int. Dále int+ by znamenalo jeden nebo více intů a int* by znamenalo libovolný počet intů. Tyto konstrukce by de facto deklarovaly kolekce a umožnily by pohodlnější práci s daty. Na druhé straně by však přinesly (další) zesložitění jazyka a je možné, že někteří programátoři by je ani nemuseli pochopit. Navíc pak zejména konstrukce int* je pro svou zaměnitelnost se zcela odlišným prvkem jazyka 1 Poznámka: Jazyk C# podporuje ukazatele stejně jako C++, pouze musíme části kódu, kde ukazatele používáme, uzavřít do bloku unsafe.

(s ukazateli) mnoha lidem vyloženě trnem v oku. Podrobněji je tato problematika rozebrána v dokumentu z Microsoft Research [4]. 3. Zatímco zde byl vyřešen problém nulovatelných typů, ticho zůstalo v otázce nenulovatelných typů, jak je známe z C++. Jazyk C# totiž dodnes neobsahuje konstrukci, jak zapsat kód ekvivalentní referencím jazyka C++, tedy referencím, do kterých nelze přiřadit null. Zatímco v C++ to lze obejít přetypováním přes ukazatel, v C# by to díky silnější typové kontrole mohlo fungovat ještě lépe. Jak ukazují některé studie, přidáním tohoto prvku by se mohla zvýšit bezpečnost i jednoduchost kódu, neboť na většině míst opravdu null hodnoty (místo skutečných objektů) vůbec nechceme. Pro podrobnější diskuzi viz [5]. 5 Závěr Nulovatelné typy jsou novým prvkem jazyka C#. Ačkoliv jejich použití se v praxi možná omezí jen na práci s relačními databázemi, principiálně jde o velmi zajímavý prvek, který nabízí jistý zobecněný pohled na chápání hodnotových datových typů. Při hlubším zkoumání nulovatelných typů navíc vidíme i prostor k debatám nad dalšími možnými zobecněními, což můžeme pro výzkum v oblasti programovacích jazyků považovat za velmi přínosné. Další informace je možno hledat ve všech publikacích zmíněných v textu a také na stránkách MSDN [6], MSDN Lab. [7] nebo MSDN Magazine [8]. Literatura 1. Hejlsberg, A., Golde, P. a Katzenberger, S. C# Version 2.0 Specification. Microsoft 2004. http://msdn.microsoft.com/vcsharp/team/language/ 2. Keprt, A. Horké novinky v jazyce C# 2.0 (1.část). V časopise ComputerWorld. Ročník 15, číslo 42/2004. ISSN 1210-9924. 3. Keprt, A. Nové prvky jazyka Visual C# 2.0 (2005). Ve sborníku konference Objekty 2004. Ed. David Ježek, Vojtech Merunka, VŠB Technická Univerzita, Ostrava, 2004, pp. 15 32, ISBN 80-248-0672-X. 4. Meijer, E. a Schulte, W. Unifying Tables, Objects and Documents. Microsoft Research. http://research.microsoft.com/~emeijer/papers/xs.pdf 5. Najmabadi, C. Who Wants Non-Nullable Types? In MSDN Blogs. http://blogs.msdn.com/cyrusn/archive/2004/06/03/147778.aspx 6. MSDN centrum nápovědy a dokumentace http://msdn.microsoft.com/ 7. MSDN Lab. laboratoř pro beta verze produktů apod. http://lab.msdn.microsoft.com/ 8. MSDN Magazine časopis serveru MSDN http://msdn.microsoft.com/msdnmag/ 9. Visual Studio 2005 Beta Documentation http://msdn2.microsoft.com/