Yoda conditions
A héten felmerült egy kérdés egyik kollégánktól, hogy mi értelme van annak, ha egy if utasÃtás feltételében megfordÃtjuk az operandusok sorrendjét? Nézzük meg!
ElÅ‘ször is tisztázzuk, hogy mit is jelent, ha megfordÃtjuk az if utasÃtás feltételében az operandusok sorrendjét. Ez azt jelenti, hogy a megszokott:
if (változó == valami) {
//kód
}
helyett
if (valami == változó) {
//kód
}
módon Ãrjuk meg a feltételeket, ahol a valami egy konstans, amihez hasonlÃtunk.
Ezt a programozói szaknyelv Yoda condition néven ismeri. A Yoda condition a nevét nem meglepÅ‘ módon Yoda-ról kapta, pontosabban a beszédstÃlusáról.
Eredeti nyelven Yoda beszéde a hagyományos angoltól eltérően nem az alany-ige-tárgy sorrendet követi, hanem általában az alany-tárgy-ige sorrendet. Ezt a szósorrendet tipikusan egyébként akkor szokás használni, ha valamit hangsúlyozni szeretnénk.
Pl: „She wants to fight, and fight she will”.
Ennyi angol és nyelvtani felvezető után visszatérve a programozásra felmerülhet a kérdés, hogy mi értelme van ennek a szintaxisnak?
A rövid válasz az, hogy C# esetén semmi, csak annyi, hogy a kódunkat nehezebb lesz olvasni. Persze akkor felmerül a másik kérdés, hogy mégis milyen nyelvek esetén van értelme?
Például C/C++ esetén van haszna, mivel itt az if utasÃtásban nem csak összehasonlÃtani tudunk, hanem értéket is tudunk adni a változóknak:
if (valtozo = 42) {
/*kód*/
}
A fenti C/C++ kódrészlet simán lefordul, de nem sok értelme van Ãgy a feltételnek. Viszont ha ezt a kifejezést Yoda condition-re alakÃtjuk, akkor a kód nem fog fordulni, mivel az = operátor bal oldalán kell állnia annak, aminek értéket adunk.
/*fordÃtási hiba*/
if (42 = valtozo) {
/*kód*/
}
Ezen felül Java és olyan nyelvek esetén is lehet értelme, ahol a == jel nem felüldefiniálható és mindig referenciát hasonlÃt össze. Nézzünk egy példát!
String x = null;
if (x.equals("foo")) {
//kivétel fog keletkezni.
}
A fenti kódrészletetbÅ‘l belátható, hogy egy kivétel fog keletkezni, mivel null objektumon nem hÃvható metódus és x változó értékét nem ellenÅ‘riztük le null-ra. Viszont ha megfordÃtjuk a sorrendet, akkor nem fog kivétel keletkezni:
String x = null;
if ("foo".equals(x)) {
//Nem keletkezik kivétel
}
Ebben az esetben a konstans, létezÅ‘ objektumon lesz meghÃvva a metódus, ami nem dob kivételt, mert lekezeli, hogy x lehet null értékű.
A fenti példákból látható, hogy C# esetén nem sok értelme van a Yoda condition használatának, mivel az if utasÃtás feltételeinek bool tÃpusra kiértékelhetÅ‘nek kell lenniük, valamint a == felülÃrható (kifejezetten ajánlott egyébként, ha a tÃpus implementálja az IEquatable<T> interfészt) és a ?. operátorral null ellenÅ‘rizve tudunk egy objektum tulajdonságához hozzáférni.
Egyetlen „elÅ‘nye”, hogy növeli a kód kognitÃv komplexitását, vagyis több idÅ‘ kell a megértéséhez és módosÃtásához. Éppen ezért a fejlett refactor eszközök, mint a Roslinator, felismerik ezt a mintát és automatikusan át tudják Ãrni a feltételt a megszokott formára.
Összegezve tehát a Yoda condition valamikor hasznos volt, de manapság egyre kevesebb értelme van. C/C++ esetén a feltételen belüli értékadásból adódó hibákat szinte bármelyik statikus kód analizátor meg tudja fogni. Statikus kód analizátort pedig projekt mérettől függetlenül érdemes használni.


2022.03.02. @ 10:47
(Az interface neve helyesen IEquatable.)
2022.03.02. @ 10:53
Köszi, javÃtottam.