C# 4.0 újdonságok – Opcionális paraméterek
2009. november 2. Hozzászólás
COM komponensek és a C# mostanáig
Az opcionális paraméterek egy olyan funkció melyet régóta hiányol a C# közösség a nyelvből, ami teljesen érthető, ha már használtunk COM komponenseket C# alól. Elég ha csak megnézzük a következő 2 példakódot amik ugyanazt csinálják, csak az egyik C# kód, a másik pedig Visual Basic.
C#
Visual Basic
Mindkettő program a Word helyesírás ellenőrzőjét használja. De vajon ha ugyanazt a függvényt használják miért ez a nagy különbség? Mivel a C++ már régen támogatja az opcionális paramétereket (Ugyan erre a dologra Stroustrup könyve az alapértelmezett paraméterek elnevezést használja.), így nagyon sok függvényt úgy írtak meg, hogy ezt a lehetőséget kihasználják. Ilyen a fent is látott CheckSpelling függvény. A C# viszont eddig nem támogatta ezt a lehetőséget, így COM komponensek használatánál kénytelenek voltunk minden egyes opcionális paraméternek is értéket adni( Ami sok számú paraméternél "érdekesen" festett. Elég megnézni EZT a linket elrettentő példának.). Erre volt jó a Type.Missing típus. Hála az égnek csak volt mert a C# 4.0ás verziója immár támogatja az opcionális paramétereket.
Szintaxis
Hogyan is néz ki a dolog a gyakorlatban? Nagyon egyszerű dolgunk van ha opcionális paramétereket akarunk definiálni semmi mást nem kell tennünk, mint a paraméter neve után megadni egy alapértelmezett értéket. Például nézzük a következő függvényt ami alapból azt írja ki nekünk, hogy Hello World:
A függvényt ezek után ugyan úgy hívhatjuk meg, mint eddig is kivéve, hogy az opcionális paramétereknek nem muszáj értéket adnunk, ez esetben az lesz az értéke, amit a függvény deklarálásakor megadtunk neki. Ennek megfelelően a fenti függvényt több féle paraméterezéssel is meghívhatjuk:
A kimenet pedig a következő lesz:
Ugye nem is bonyolult dolog? Az igazsághoz hozzátartozik, hogy korában is tudtunk opcionális paramétereket definiálni attribútumok segítségével, de ettől még a COM komponensek használatánál szükség volt a fent is említett Type.Missingre.
Pár fontos tudnivaló
Mint minden dolognál azért itt van pár dolog amire oda kell figyelnünk. Adjunk a függvényünkhöz még egy paramétert a többi után, de ez ne legyen opcionális!
Láthatjuk, hogy a VS már eleve aláhúzta az új paramétert, de azért próbáljuk meg lefordítani a kódot ami a következő hibaüzenetet fogja eredményezni:
Az opcionális paraméterek csakis a kötelező paraméterek után következhetnek. Ennek oka a következő, nézzük meg ezt a függvényt például:
Itt vajon, hogyan dönti el a fordító, hogyha egy adatot adunk meg bemenő adatként, akkor azzal az elsőt akarjuk felülírni, vagy a másodiknak akarunk értéket adni? Emiatt az opcionális paramétereket mindig a kötelezők után kell írni.
Most már tudjuk, hogy az opcionális paramétereket mindig a paraméterlista végén adjuk meg. Nézzük a következő esettet mikor a függvény és az azt használó program két külön fájlban (esetünkben két külön projectben) van.
Fordítsuk le és futtassuk a fenti programot ekkor a már fentebb is látott kimenetet kapjuk:
Ezek után a Write függvényünk egyik paraméterének írjuk át az alapértelmezett értékét. Mondjuk a b-nek ne World legyen az értéke, hanem Józsi.
Ezek után fordítsuk újra a függvényt tartalmazó DLL-t de csakis azt, azt használó programot ne! Az eredmény a következő lesz:
Ez valljuk be nem egészen az amire számítottunk. Itt még mindig "Hello World!"-öt kapunk eredményül az első hívásnál, pedig már átírtuk sőt újra is fordítottuk a DLL-űnket. Ha viszont újra fordítjuk a hívó programunkat is, akkor immár a helyes eredményt fogjuk kapni:
Ennek oka abban keresendő ahogy az IL tárolja az opcionális paraméterek alapértelmezett értékeit. A fordító ezeket az értékeket egy úgynevezett Constant Table-ben fogja eltárolni, fordítási időben, és aminek az eléréséhez nincs az ILnek megfelelő utasítása futási időben. Magyarul szólva ezeket az alapértelmezettként megadott értékeket a fordító beleégeti a programba, ami meghívja őket. Tehát ha később szeretnénk egy opcionális paraméter értékét módosítani, akkor kénytelenek vagyunk minden programot újra fordítani, amely használja, különben a régi értéket fogja a programunk továbbra is használni.
Konklúzió
Ezek után mit lehet még elmondani az opcionális paraméterekről? Mindenképpen egy praktikus új funkcióval bővült a nyelv, ami megkönnyíti a régi COM komponensekkel való munkát, de nem árt odafigyelni, hogy csak olyan paramétereket tegyünk opcionálissá saját programjainkban, amiket később se fogunk majd módosítani.
További linkek a témával kapcsolatban:
B#.NET Blog – C# 4.0 Feature Focus – Part 1 – Optional parameters
Channel 9 – C# 4.0 New Features – Optional Parameters
A bejegyzésben láttható példa kódok:
Legközelebb megnézzük, hogy mi a teendő akkor ha egy több opcionális paramétert tartalmazó, függvénynek csak az egyik (de nem az első) paraméterének akarunk új értéket adni. Azaz jönnek a "named" paraméterek (Ha valaki tud erre egy jó magyar szót akkor kérem ne tartsa titokban előttem.).











