Hrátky s Nullable typy

Tomáš Herceg       16. 9. 2013       C#       5589 zobrazení

Že můžete v .NETu za každý hodnotový typ doplnit otazník a udělat z něj nullable typ, je asi jasné. Do takové proměnné lze přiřadit jak hodnotu, tak i null. Vzhledem k tomu, že teď často pracuji s kódem jiných lidí, vídám různé způsoby, jak s těmito typy pracovat.

Zajímalo by mě, jak řešíte následující situace.

Test null hodnoty

Znáte to, máme proměnnou int? test a chceme zjistit, jestli je v ní null nebo ne.

Používáte test.HasValue nebo test != null?

 

Ternární operátor

Známým problémem u nullable typů je fakt, že pokud použijeme ternární operátor, který v jedné větvi vrací int a ve druhé null, kompilátoru se to nelíbí. Ten null je nutné přetypovat na int?, aby kompilátor věděl, jakého typu ta hodnota je.

Nelze tedy napsat něco jako

public int? ToNullableInt(string value) 
{
    int a;
    return int.TryParse(value, out a) ? a : null;
}

Aby to fungovalo, musíme null přetypovat na int?, vypadalo by to tedy takto:

return int.TryParse(value, out a) ? a : (int?)null;

Nedávno jsem ale viděl řešení, které by mě nenapadlo:

return int.TryParse(value, out a) ? a : new int?();

Které řešení upřednostňujete vy?

 

hodnocení článku

1 bodů / 1 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

Dalsie extension metody pre nullable

Pouzivam este takuto extension metodu pre nullable, ktora otestuje objekt zadany ako generic <T> ci je nullable alebo nie. Nemylit si testovanim na hodnotu "null"!

public static bool IsNullable<T>(this T obj)
{
    if (obj == null)
    {
        return true;
    } 

    Type type = typeof(T);

    if (!type.IsValueType || Nullable.GetUnderlyingType(type) != null)
    {
        return true;
    } 

    return false;
}
nahlásit spamnahlásit spam 0 odpovědětodpovědět

hrátky s nullable typy

Inspirovalo me to neco k tomu vydloubat: http://blog.cincura.net/233417-nullable-... .

nahlásit spamnahlásit spam 0 odpovědětodpovědět

VB.NET verze

S tímto VB.NET kompilátor nemá žádný problém ani při Option Strict On a nenapadá mě žádný případ, kdy by se to chovalo jinak než podle očekávání.

Public Function ToNullableInt(value As String) As Nullable(Of Integer)
  Dim n As Integer
  Return If(Integer.TryParse(value, n), n, Nothing)
End Function
nahlásit spamnahlásit spam 0 odpovědětodpovědět

ReferenceEquals

Ještě mě napadla tato validace:

int? a = null;
if(ReferenceEquals(a,null))
{
//a je null
}
else
{
//a neni null...
}
nahlásit spamnahlásit spam 0 odpovědětodpovědět

To zavání úplně zbytečným boxingem... (teda kromě toho, že je to jinak dost nečitelný)

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Přesně tak, zbytečný boxing a ještě je to dlouhé.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

nullable typy

Já standardně (snad jako většina) používám test != null a int.TryParse(value, out a) ? a : (int?)null a jsem dost rád, že jiné varianty moc často nevídám.

U druhého případu jsem se občas ještě setkal s variantou int.TryParse(value, out a) ? (int?)a : null, ale osobně preferuju tu první (v druhém případě nemusí být zřejmé, proč tam to přetypování je).

Jinak new int?() je přesně to co, kompilátor místo (int?)null vygeneruje, protože nemá ani jak jinak hodnotu null daného typu vyrobit (a nějak to interně implementované být musí).

Ještě doporučuji tyto zajímavé články, které se nullable typy zabývají:

http://ericlippert.com/2012/12/20/nullab...

http://ericlippert.com/2012/12/27/nullab...

http://blogs.msdn.com/b/ericlippert/arch...

nahlásit spamnahlásit spam 3 / 3 odpovědětodpovědět

Souhlas, dělám to stejně - test != null (protože je to konzistentní s referenčními typy, které HasValue nemají) a (int?)null - je to výstižnější než přetypovávat na int? ten integer.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jen ještě doplním pro ty VB.NETaře

Pamatuju si na jeden případ, kdy se pro kontrolu zda nullable typ je Null (Nothing) MUSELO používat HasValue, jednalo se o VB 8.0 (to je ten ve VS 2005), tam ještě nechodilo porovnání If Test Is Nothing Then, jedinej možnej zápis byl If Not Test.HasValue Then

Také tam tuším ještě nešlo použít ? a místo Dim Test As Integer? se psalo Dim Test As Nullable(Of Integer)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

vb.net

Kdysi byl tento web zaměřen na VB.NET, čímž byl něčím vyjmečný a pro mě i zajimávý, protože mám VB.NET radši než ten síšarp, trochu mě štve, že ani Vy nejste schopen ten kód napsat ve VB.NET.

nahlásit spamnahlásit spam 1 / 3 odpovědětodpovědět

On nikdy nebyl zaměřen úplně primárně na VB.NET, jen se tak jmenoval.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

ani Vy nejste schopen ten kód napsat ve VB.NET

Já samozřejmě jsem schopen napsat ten kód ve VB.NET, nevím, kde jste přišel na takový nesmysl.

Ale aktuálně víc používám C# a stejně tak to má většina .NET vývojářů, proto píšu ukázky kódu v C#.

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Já osobně...

Já osobně teda používám != null, o tom druhém způsobu jsem ani nevěděl. Ternární operátor jsem ještě v kombinaci s nullable typy nepoužil, ale víc se mi líbí řešení s (int?)null...

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback