Ale ne, nebojte, chápu to. A velmi dobře. Jen to domýšlím mnohem dál než vy. Nemusíte sem psát co a k čemu jsou Nullable typy. Že když máme třeba int, u kterého jsou si všechny hodnoty jeho rozsahu (-1, 0, cokoliv jiného) navzájem rovny, tak není příliš vhodné (i když principiálně možné) jednu z nich volit pro speciální hodnotu označující "neznámá hodnota"/"neurčeno"/"nezadáno" (prostě null) (ve VB.NET tomu říkají Nothing, protože na to stejně jako u C# použili stejné klíčové slovo, které u referenčních typů označuje referenci, která neukazuje na žádný objekt, ale s null/Nothing referencí to nijak nesouvisí), a proto použijeme monad Nullable<T>, který k hodnotám hodnotového typu T přidá hodnotu null. To ví každý. My tu ale řešíme Enum. A navíc konkrétní modelový případ, kdy nás u něho zajímají pouze hodnoty 1 (Alfa) a 2 (Beta) a dále potřebujeme hodnotu s významem "nezadáno". Vy na to mechanicky a slepě aplikujete to co jsem výše uvedl pro int (výjde vám varianta 2) a máte hotovo. Je to ale pro tento případ jediné správné řešení? A pokud ne, není jiné řešení dokonce lepší? Enum tak jak je v jazyce C# a v .NETu interně implementován je hodnota nějakého "underlying" celočíselného numerického hodnotového typu (pokud ho neuvedeme je jím int, ale může to být i byte, short nebo long), pouze s tím rozdílem, že jeho některé námi zvolené hodnoty pojmenujeme a můžeme se na ně pak tím zvoleným jménem odkazovat. Nikdo nám ale nikdy nezaručí, že v proměnné, která je typu Enum, nebudou jiné hodnoty jeho "underlying" typu. Navíc "underlying" typ Enumu je hodnotový typ, což znamená, že i Enum je hodnotový typ. A u každého hodnotového typu nutně existuje "prázdná" hodnota, která odpovídá tomu, když obsah jeho paměti obsahuje pouze nuly (u Enumu tedy 0). A mimochodem, aby jsme uměli jednoduše testovat, zda nemá emum prázdnou hodnotu, říká guideline, že máme hodnotu 0 u každého Enumu rovnou pojmenovat např. právě None. A pak můžeme psát:
Options[] array = new Options[10];
Debug.Print(array[0] == Options.None);
místo
Debug.Print((int)array[0] == 0);
Nyní zpět k našemu modelovému případu. Když každý Enum má stejně hodnotu 0/None, kterou my konkrétně pro Alfa ani Beta nevyužíváme, nebylo by správnější rovnou tuto hodnotu použít pro reprezentaci hodnoty "nezadáno", místo zavádění hodnoty null? Navíc potřebujeme zde umět 0 a null odlišit? Ne, naopak, pokud budeme "nezadáno" reprezentovat v DB jako 0 budeme muset nějak zajistit, že se 0 bezpodmínečně vždy převede na null (pokud zase bude v DB null, budeme muset CHECK constraintem zajistit, že do db nepůjde uložit 0). Takže použití 0/None je zajisté jednodušší a přitom to vypadá, že nic oproti řešení s null neztrácí.
|