Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Tip
Ez a cikk az Alapismeretek szakasz része azon fejlesztők számára, akik már legalább egy programozási nyelvet ismernek, és c#-t tanulnak. Ha még csak most ismerkedik a programozással, először az Első lépések oktatóanyagokkal kezdje.
Más nyelvről jön? A C#-kifejezések ugyanúgy működnek, mint Java, C++ és JavaScript nyelven. Egy különbség, amit érdemes megjegyezni: az összetett hozzárendelési operátorokhoz hasonló += és a növekményes operátorok ++ a C# kifejezései, így nagyobb kifejezésekben is megjelenhetnek.
A kifejezés olyan kódrészlet, amelyet a fordító kiértékel, hogy értéket állítson elő – számot, sztringet, hivatkozást vagy egy bool. Például a 3 + 4 * 2 egy olyan kifejezés, amelynek értéke a(z) 11 egész szám, a total > 10 pedig egy olyan kifejezés, amelynek értéke true vagy false.
A legegyszerűbb kifejezések a literálok (mint például 42 vagy "hello") és a változónevek (mint például total). Összetettebb kifejezéseket hozhat létre az egyszerűbbek és az operátorok kombinálásával.
Kifejezések és állítások
Egy kifejezés értéket hoz létre. Az utasítás egy teljes utasítás, amelyet a program végrehajt. Számos utasítás tartalmaz kifejezéseket. Például int total = 3 + 4 * 2; egy változó deklarációs utasítás. A fordító kiértékeli az inicializáló kifejezést 3 + 4 * 2, amely létrehozza 11, és hozzárendeli ezt az értéket az új változóhoz total.
Úgy tekinthet egy kifejezésre, mint egy szókapcsolatra, egy C#-utasításra pedig mint egy teljes mondatra. Ezek a munkadefiníciók segítenek megérteni azokat a formális terminológiát és magyarázatokat, amelyekkel a C#-ról való tájékozódás során találkozhat, bár a szokásos kódolás ritkán igényli, hogy tudatosan emlékezzen a megkülönböztetésre.
Kifejezések kombinálása
A kifejezések kombinálhatók. Fontolja meg 3 + 4 * 2. Ez az egyetlen kifejezés valójában két kisebb kifejezést tartalmaz: a szorzási kifejezést4 * 2 és az összeadási kifejezést3 + <result>. A kifejezések kombinálásakor a C#-nak egy szabályra van szüksége annak eldöntéséhez, hogy melyiket kell először kiértékelni. Ez a szabály az operátorok elsőbbsége.
Nem kell megjegyeznie a teljes elsőbbségi hierarchiát. A következő szakasz összefoglalja a mindennapi csoportokat, és zárójelekkel mindig egyértelművé teheti a rendelést, ha nem biztos benne.
Operátorok elsőbbsége
Az operátorok elsőbbsége határozza meg, hogy egy kombinált kifejezés hogyan csoportosítható részkifejezésekké. Ez a fogalom hasonló a matematikai osztály műveleti sorrendjének szabályaihoz. A magasabb elsőbbséget élvező operátorok szorosabban kötődnek az operandusokhoz. A kifejezés úgy van felépítve, mintha ezek az operandusok együtt zárójelezve lennének. A(z) 3 + 4 * 2 esetén a(z) * nagyobb precedenciával rendelkezik, mint a(z) +, ezért a kifejezés így csoportosul: 3 + (4 * 2), nem pedig (3 + 4) * 2.
A C#-nak több előzménycsoportja van, mint az itt összefoglalt négynek. Ezek a további csoportok az ismert szabályokat – például a hozzáadás előtti szorzást – kényszerítik ki, és lefedik az operátorok teljes készletét. A következő csoportok a mindennapi kódban leggyakrabban előforduló problémákat ismertetik:
-
Elsődleges, unáris és intervallum – ez három különálló elsőbbségi csoport, amelyek mindegyike erősebben kötődik, mint az aritmetikai műveletek. Ez az összefoglalás egyetlen lépésben egyesíti őket, mert gyakorlati célokra mind az aritmetika előtt alkalmazhatók.
-
Az elsődleges operátorok – a tagok hozzáférése (
x.y), a metódushívások (f()), az indexelés (a[i]) és a null-feltételes hozzáférés (?.,?[]) – a legszorosabban kötődnek. -
Az unáris operátorok egyetlen operandusra alkalmazhatók: negáció (
-x), logikai NOT (!flag), prefix növelés (++i) és postfix növelés (i++). - A tartomány operátora (
..) indextartományokat hoz létre szeletkifejezésekhez, példáularray[1..4].
-
Az elsődleges operátorok – a tagok hozzáférése (
-
Aritmetikai műveletek — a
*,/és%szorosabban kötődik, mint a+és-. A szorzás és osztás az összeadás és kivonás előtt történik. -
Összehasonlítás —
<,>,<=,>=,==,!=gyengébben kötődik, mint az aritmetikai műveletek, így azok az összehasonlítás előtt hajtódnak végre. -
Logikai –
&&és||a közös operátorok közül a legkevésbé szoros kötés, ezért az összehasonlítások a logikai kombináció előtt befejeződnek.
Ez a precedencia azt jelenti, hogy a(z) score + bonus > threshold && attempts < maxAttempts kifejezés pontosan úgy értékelődik ki, ahogyan olvasná: adja össze a(z) score és bonus értékét, hasonlítsa össze az összeget a(z) threshold értékkel, hasonlítsa össze a(z) attempts értéket a(z) maxAttempts értékkel, majd kombinálja a két bool eredményt a(z) && operátorral. Ha zárójeleket ad hozzá, hogy minden csoportosítás explicit legyen, ugyanaz a struktúra jelenik meg: ((score + bonus) > threshold) && (attempts < maxAttempts).
Az összes operátorra kiterjedő teljes elsőbbségi hierarchiát a C#-operátorok és -kifejezések című témakörben tekinti meg.
A szándék egyértelművé tétele zárójelekkel
Zárójelek felülbírálják az elsőbbséget, és egyszerre dokumentálják a szándékot. Ha a fenti csoportok nem egyértelműek a sorrendben, zárójeleket adjon hozzá:
int score = 80;
int bonus = 15;
int threshold = 90;
bool eligible = true;
// Without parentheses: || binds less tightly than &&, so this reads as:
// eligible && (score + bonus > threshold) || bonus > 20
bool result1 = eligible && score + bonus > threshold || bonus > 20;
// With parentheses: forces the || to combine two complete conditions
bool result2 = (eligible && score + bonus > threshold) || bonus > 20;
Console.WriteLine(result1); // => True
Console.WriteLine(result2); // => True
// Parentheses can also change the result:
bool isAdmin = false;
bool isOwner = true;
// Without: && binds tighter, so: (isAdmin && isOwner) || true
bool access1 = isAdmin && isOwner || true;
// With: forces the || to run first
bool access2 = isAdmin && (isOwner || true);
Console.WriteLine(access1); // => True (false && true is false; false || true is true)
Console.WriteLine(access2); // => False (false && anything is false)
Az utolsó két sor azt mutatja, hogy a zárójelek nem csak a stílust, hanem az eredményt is megváltoztathatják. Amikor && és || együtt jelennek meg, zárójelek hozzáadásával adja meg, hogy melyik feltétel egyesül először. Egy olvasó, aki látja (isAdmin && isOwner) || isSuperUser , azonnal ismeri a szándékot.
Kifejezések kiértékelése
Egy hasonlattal könnyebben megérthető, hogy a C# hogyan értékeli ki a kombinált kifejezéseket. Képzelje el a ceruzával és a papírral kapcsolatos összetett matematikai probléma megoldását: azonosítja a legbelső vagy legmagasabb prioritású alkifejezést, kiszámítja annak köztes értékét, írja le az eredményt, majd ismételje meg a következő alkifejezéssel – amíg el nem éri a végső választ.
A C# ugyanazt a folyamatot követi, amelyet két szabály vezérel:
1. szabály: Az operandusok balról jobbra értékelnek. Minden bináris kifejezés esetében mindkét operandust teljes mértékben ki kell értékelni az operátor alkalmazása előtt. A C# először kiértékeli a bal operandust, majd a jobb oldalt, majd végrehajtja a műveletet.
2. szabály: Egyes operátorok rövidzárlatban vannak. Bizonyos operátorok az eredmény meghatározása után leállnak az értékelés során, kihagyva a fennmaradó operandusokat:
-
&&(feltételes ÉS): visszaadja a(z)falseértéket, amint a bal oldali értékfalse. A jobb oldal soha nincs kiértékelve. -
||(feltételes VAGY): a(z)trueértéket adja vissza, amint a bal oldaltrue. A jobb oldal soha nincs kiértékelve. -
?:(feltételes/ternáris): csak a feltételnek megfelelő ágat értékeli ki – a másik ág soha nem lesz kiértékelve. -
?.(null-feltételes taghozzáférés) és?[](null-feltételes elemhez való hozzáférés): állítsa le és adja visszanullazonnal, amikor a bal oldalon vannull, kihagyva a taghozzáférést vagy az indexet. -
??=(null-egyesítő értékadás): csak akkor rendeli a jobb oldali értéket, ha a bal oldali értéknull.
Papír-ceruza alapú értékelés
Fontolja meg a kifejezést 3 + 6 / 2. Annak ellenére, hogy az összeadás jelenik meg elsőként az olvasási sorrendben, a / precedenciája magasabb, mint a +-é, ezért a 6 / 2 az az alkifejezés, amely először értékelődik ki. Lépésről lépésre haladva – pontosan úgy, ahogy papíron tenné:
3 + 6 / 2
↓ (evaluate 6 / 2 → 3)
3 + 3
↓ (evaluate 3 + 3 → 6)
6
// 3 + 6 / 2
// Step 1: 6 / 2 has higher precedence → interim value 3
// Step 2: 3 + 3 → final result 6
int result = 3 + 6 / 2;
Console.WriteLine(result); // => 6
A(z) + által előállított köztes érték, 3, a(z) 6 jobb oldali operandusává válik, a végeredmény pedig 6 / 2. Minden alkifejezés létrehoz egy köztes értéket; ezek a köztes értékek a következő alkifejezést táplálják, amíg csak egy érték marad.
Az asszociativitás egy kapcsolódó fogalom: ha két operátor azonos elsőbbséget élvez, az asszociativitás dönti el, hogy melyik legyen az első. A C# -operátorok többsége bal asszociatív, ami azt jelenti, hogy balról jobbra csoportosítja őket. Tehát a - b - c ugyanaz, mint (a - b) - c, nem a - (b - c).
Rövidzárlat-értékelés a gyakorlatban
A rövidzárlatok kiértékelése különösen hasznos null értékű ellenőrzések esetén:
string? text = null;
// Safe: second condition runs only when text is not null
bool hasContent = text != null && text.Length > 0;
Console.WriteLine(hasContent); // => False (short-circuits after null check; no NullReferenceException)
text = "hello";
hasContent = text != null && text.Length > 0;
Console.WriteLine(hasContent); // => True
// || short-circuits on true: right side is never evaluated when left side is true
string word = "hello";
bool anyMatch = word.StartsWith("h") || word.StartsWith("x");
Console.WriteLine(anyMatch); // => True (right side never evaluated)
// ?. short-circuits on null: returns null without accessing .Length
string? maybeNull = null;
int? length = maybeNull?.Length; // length is null; no NullReferenceException
Console.WriteLine(length.HasValue); // => False
text != null && text.Length > 0 biztonságos, mert a második feltétel csak akkor fut, ha text nem null. Hasonlóképpen, a ?. leállítja a kiértékelést, amikor egy null referenciával találkozik, így elkerülhető egy NullReferenceException explicit if ellenőrzés nélkül.
A nullbiztos operátorok részletesebb áttekintéséért tekintse meg a C# null operátorok című témakört.
Lásd még
- C# operátorok és kifejezések (nyelvi referencia) – teljes elsőbbségi táblázat és minden operátor
- Számtani, összehasonlító, logikai és hozzárendelési operátorok – a mindennapi operátorok részletes bemutatása
-
Egyenlőségi összehasonlítások – hogyan
==,!=ésEqualshogyan működnek -
C# null operátorok —
?.,??és??= - Boole-i logikai operátorok