C# ja küsimärgid
02.01.2008 | Gunnar
Üks huvitavaid operaatoreid, mille C# meile pakub, on operaator ??, selle kasutamiseks on aga tore teada, mida teeb ?. Võtan selle kandega mõlemad küsimärgid kokku. Tegutsemise käigus piilume korra ka kompilaatori poolt toodetud koodi ning vaatame, kas ootab meid seekord sealgi mõni üllatus või ei.
Alustuseks vaatame ühekordset küsimärki. See võimaldab lühikesi Nullable tüüpide deklaratsioone. Vaatame järgmist näidet.
{
static void Main(string[] args)
{
Int32? x;
Nullable<Int32> y;
}
}
Kui oleme selle kompileerinud, näeme järgmist IL koodi.
{
.entrypoint
// Code size 2 (0x2)
.maxstack 0
.locals init ([0] valuetype [mscorlib]System.Nullable`1<Int32> x,
[1] valuetype [mscorlib]System.Nullable`1<Int32> y)
IL_0000: nop
IL_0001: ret
} // end of method Program::Main
Näeme, et nii küsimärgiga Int32 kui ka Nullable<Int32> toodavad meile samasuguse vahekoodi. Seega võime olla kindlad, et tüübile küsimärgi järgi kirjutamisel saame samasuguse tulemuse kui tüübile vastava Nullable<> defineerimisel.
Vaatame nüüd, kuidas saame kasutada kahte küsimärki. Muudame natukene eelmist näidet, nii et x oleks NULL ja y ei oleks NULL. Seejärel laseme ekraanile trükkida ?? abil saadava tulemuse.
{
static void Main(string[] args)
{
Int32? x = null;
Nullable<Int32> y = 15;
Console.WriteLine(x ?? y);
Console.ReadLine();
}
}
Kui antud koodi kompileerime ja käivitame, siis trükitakse konsoolile tulemuseks 15. Seega saame me kasutada ?? operaatorit sarnaselt T-SQL'i funktsioonile COALESCE.
Järgmiseks teeme nii, et x ja y mõlevad omavad väärtust NULL ning püüame ?? operaatorit kahekordselt kasutada. Kood on selline.
{
static void Main(string[] args)
{
Int32? x = null;
Nullable<Int32> y = null;
Console.WriteLine(x ?? y ?? 10);
Console.ReadLine();
}
}
Vigu ei tule ning peale kompileerimist ja käivitamist kirjutatakse konsoolile kenasti tulemus 10. Täpselt see, mida ootasime!
Operaator ?? eeldab, et temast mõlemale poole jäävad muutujad on samat tüüpi. Eelnevates näidetes oli meil selleks tüübiks Nullable<Int32>. Proovime, mis juhtub, kui soovime tagastada ühel juhul täisarvu ja teisel korral stringi.
{
static void Main(string[] args)
{
Int32? x = null;
string y = "test";
Console.WriteLine(x ?? y);
Console.ReadLine();
}
}
Tulemuseks on järgmine viga.
Operator '??' cannot be applied to operands of type 'int?' and 'string'
Seega peame me kasutama samu Nullable tüüpe või vähemasti tüüpe, mille jaoks on defineeritud implicit cast.

02.01.2008 kell 23:14
Hehe, väike märkus; operaator “??” ja “int?” olid olemas juba C# 2 ajal visual studio 2005′ga
02.01.2008 kell 23:48
Ptui, versioon läks automaatselt sassi