Πότε, γιατί και πώς να τις χρησιμοποιούμε σωστά
Εισαγωγή
Στην C#, οι conditional expressions (γνωστές κυρίως μέσω του ternary operator ?:) προσφέρουν έναν σύντομο και εκφραστικό τρόπο να αντικαταστήσουμε απλά if/else blocks με μία γραμμή κώδικα.
Ωστόσο, η υπερβολική ή λανθασμένη χρήση τους μπορεί να οδηγήσει σε δύσκολα αναγνώσιμο και δυσυντήρητο κώδικα.
Σκοπός του άρθρου είναι:
- Να παρουσιάσει όλες τις μορφές conditional expressions
- Να εξηγήσει πότε είναι σωστό να χρησιμοποιούνται
- Να δείξει πότε πρέπει να αποφεύγονται
- Να παραπέμψει σε επίσημη τεκμηρίωση Microsoft
1 Conditional (Ternary) Operator ?:
Σύνταξη
condition ? expressionIfTrue : expressionIfFalse;
Παράδειγμα
var status = isActive ? "Enabled" : "Disabled";
Ισοδύναμο με:
string status;
if (isActive)
status = "Enabled";
else
status = "Disabled";
Πότε να το χρησιμοποιούμε
✔ Όταν έχουμε δύο απλές επιλογές
✔ Όταν το αποτέλεσμα είναι απλό expression
✔ Όταν βελτιώνει την αναγνωσιμότητα
Πότε να το αποφεύγουμε
❌ Όταν οι εκφράσεις είναι μεγάλες
❌ Όταν περιέχουν business logic
❌ Όταν δυσκολεύει το debugging
📚 Microsoft Documentation:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-operator
2 Nested Ternary
var grade =
score >= 90 ? "A" :
score >= 80 ? "B" :
score >= 70 ? "C" :
"Fail";
Ανάλυση
Επιτρέπει πολλαπλές συνθήκες σε μία έκφραση.
Ωστόσο, μειώνει δραματικά την αναγνωσιμότητα.
Recommendation
Προτιμήστε switch expression αντί για nested ternary.
3 Null-Conditional Operator ?
Αποφεύγει NullReferenceException.
var name = user?.Name;
Σημαίνει: αν το user δεν είναι null, πάρε το Name, αλλιώς δώσε null.
Ισοδύναμο με:
var name = user != null ? user.Name : null;
Πότε να το χρησιμοποιούμε
✔ Όταν διαβάζουμε nested properties
✔ Όταν θέλουμε null-safe access
📚 Microsoft Documentation:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators
4 Null-Coalescing Operator ??
var name = input ?? "Default";
Αν το input είναι null → επιστρέφει "Default".
Ισοδύναμο με:
var name = input != null ? input : "Default";
ή
string name;
if (input == null)
name = "Default";
else
name = input;
📚 Microsoft Documentation:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator
5 Null-Coalescing Assignment ??=
user.Name ??= "Guest";
Αναθέτει τιμή μόνο αν η μεταβλητή είναι null.
σημαίνει “αν το user.Name είναι null, τότε βάλε "Guest"”.
Αν δεν είναι null, δεν αλλάζει τίποτα.
Το ?? λέγεται null-coalescing operator και σημαίνει “αν είναι null, πάρε το άλλο”.
- a ?? b → δίνει a αν δεν είναι null, αλλιώς b
- a ??= b → ανάθεσε στο a το b μόνο αν το a είναι null
Ισοδύναμο με:
if (user.Name == null)
{
user.Name = "Guest";
}
Χρήσιμο για:
- Lazy initialization
- Defaults
- DTO normalization
6 Throw Expressions
Από C# 7+, μπορούμε να χρησιμοποιήσουμε throw μέσα σε expression.
var user = dto.User
?? throw new ArgumentNullException(nameof(dto.User));
ή
var result = isValid
? value
: throw new InvalidOperationException();
Ιδανικό για guard clauses σε constructors ή handlers.
📚 Microsoft Documentation:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/throw
7 Pattern Matching με Ternary
var name = obj is User u ? u.Name : "Unknown";
είναι ισοδύναμο με:
User u;
if (obj is User)
{
u = (User)obj; // cast
name = u.Name;
}
else
{
name = "Unknown";
}
ή
if (obj is User u)
return u.Name;
return "Unknown";
Συνδυάζει type check + assignment.
✔ Πολύ χρήσιμο σε handlers και mapping logic.
📚 Microsoft Documentation:
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/pattern-matching
8 Switch Expressions (Modern Replacement)
var role = userType switch
{
"Admin" => 10,
"User" => 5,
_ => 0
};
Είναι ένα switch expression που μετατρέπει το userType σε αριθμητικό role:
- Αν userType είναι "Admin" → role = 10
- Αν είναι "User" → role = 5
- Για οποιαδήποτε άλλη τιμή (default _) → role = 0
Πλεονεκτήματα
✔ Πιο readable από nested ternary
✔ Καλύτερο για multiple conditions
✔ Υποστηρίζει pattern matching
📚 Microsoft Documentation:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/switch-expression
9 Advanced Pattern Matching (Property Patterns)
var message = user switch
{
null => "No user",
{ IsActive: false } => "Inactive user",
{ Role: "Admin" } => "Welcome admin",
_ => "Welcome"
};
Είναι ένα switch expression πάνω στο user που διαλέγει μήνυμα ανάλογα με την κατάσταση του:
- Αν user == null → "No user"
- Αλλιώς αν IsActive == false → "Inactive user"
- Αλλιώς αν Role == "Admin" → "Welcome admin"
- Αλλιώς → "Welcome"
Ιδανικό για business rules classification.
Πότε να χρησιμοποιούμε Conditional Expressions
Χρησιμοποιούμε ternary/conditional operators όταν:
- Θέλουμε σύντομο, καθαρό assignment
- Έχουμε απλή δυαδική επιλογή
- Θέλουμε να μειώσουμε boilerplate code
- Βελτιώνουμε readability
Πότε να τα αποφεύγουμε
- Όταν η λογική περιέχει πολλαπλά business rules
- Όταν χρειάζεται debugging με breakpoints
- Όταν δημιουργούνται nested ternary
- Όταν μειώνεται η αναγνωσιμότητα
Best Practice Guideline
✅ 1 condition → ternary
✅ Multiple discrete values → switch expression
✅ Null fallback → ??
✅ Guard clause → ?? throw
❌ Complex logic → if/else block
Να θυμάσαι..
Οι conditional expressions στην C# αποτελούν ισχυρό εργαλείο για τη δημιουργία εκφραστικού και συνοπτικού κώδικα.
Η σωστή χρήση τους βελτιώνει την αναγνωσιμότητα και μειώνει τον όγκο του κώδικα.
Η υπερβολική χρήση τους, όμως, οδηγεί σε “clever code” αντί για “clear code”.
Η αρχή που πρέπει να μας καθοδηγεί είναι:
Write code for humans first, compilers second.
Όταν το ternary κάνει τον κώδικα πιο καθαρό — χρησιμοποιήστε το.
Όταν τον κάνει πιο έξυπνο αλλά λιγότερο κατανοητό — αποφύγετέ το.
Top comments (0)