Flatten Nested Conditionals
Part of the Logic & Flow section of Coddy's C# journey — lesson 22 of 66.
Nested conditionals can make your code hard to read and maintain. Flattening helps improve readability by reducing indentation levels.
Here's an example of deeply nested conditionals:
if (userLoggedIn)
{
if (userHasPermission)
{
if (fileExists)
{
// Process the file
ProcessFile();
}
else
{
Console.WriteLine("File not found");
}
}
else
{
Console.WriteLine("No permission");
}
}
else
{
Console.WriteLine("Not logged in");
}
We can flatten this using early returns or guard clauses:
if (!userLoggedIn)
{
Console.WriteLine("Not logged in");
return;
}
if (!userHasPermission)
{
Console.WriteLine("No permission");
return;
}
if (!fileExists)
{
Console.WriteLine("File not found");
return;
}
// Process the file
ProcessFile();
Notice how the flattened code has less indentation and is easier to follow.
Challenge
EasyIn scholarship eligibility checking, deeply nested conditionals make the code hard to read and maintain. In this challenge, you'll transform a messy nested conditional structure into clean, readable code using guard clauses.
A guard clause is an early return statement that handles a specific condition right away, allowing the rest of the function to focus on the "happy path".
Your task is to complete the partially implemented guard clauses in the CheckScholarshipEligibility method according to these rules:
- If age is less than 17, return "Not eligible due to age requirement" immediately
- If GPA ≥ 3.5 AND the student has a recommendation, grant full scholarship
- If GPA ≥ 3.8, grant full scholarship (even without recommendation)
- If GPA ≥ 3.0 AND the student has a recommendation, grant partial scholarship
- If GPA is between 3.5 and 3.8, grant partial scholarship
- For all other cases, return "Not eligible for scholarship"
Cheat sheet
Nested conditionals can make code hard to read and maintain. Flattening helps improve readability by reducing indentation levels.
Instead of deeply nested conditionals:
if (userLoggedIn)
{
if (userHasPermission)
{
if (fileExists)
{
// Process the file
ProcessFile();
}
else
{
Console.WriteLine("File not found");
}
}
else
{
Console.WriteLine("No permission");
}
}
else
{
Console.WriteLine("Not logged in");
}
Use early returns or guard clauses to flatten the structure:
if (!userLoggedIn)
{
Console.WriteLine("Not logged in");
return;
}
if (!userHasPermission)
{
Console.WriteLine("No permission");
return;
}
if (!fileExists)
{
Console.WriteLine("File not found");
return;
}
// Process the file
ProcessFile();
A guard clause is an early return statement that handles a specific condition right away, allowing the rest of the function to focus on the "happy path".
Try it yourself
using System;
class Program
{
public static void CheckScholarshipEligibility(int age, double gpa, bool hasRecommendation)
{
// Guard clause for age requirement
if (age < 17)
{
Console.WriteLine("Not eligible due to age requirement.");
return;
}
// Guard clause for full scholarship with recommendation
if (/* Complete this condition */)
{
Console.WriteLine("Full scholarship granted!");
return;
}
// Guard clause for full scholarship with exceptional GPA
if (/* Complete this condition */)
{
Console.WriteLine("Full scholarship granted!");
return;
}
// Guard clause for partial scholarship with recommendation
if (/* Complete this condition */)
{
Console.WriteLine("Partial scholarship granted.");
return;
}
// Guard clause for partial scholarship with good GPA
if (/* Complete this condition */)
{
Console.WriteLine("Partial scholarship granted.");
return;
}
// Default case: not eligible
Console.WriteLine("Not eligible for scholarship.");
}
static void Main(string[] args)
{
// Test cases for immediate feedback
Console.WriteLine("Test Case 1: Age 16, GPA 4.0, Has Recommendation: True");
CheckScholarshipEligibility(16, 4.0, true);
Console.WriteLine("\nTest Case 2: Age 18, GPA 3.9, Has Recommendation: False");
CheckScholarshipEligibility(18, 3.9, false);
Console.WriteLine("\nTest Case 3: Age 17, GPA 3.6, Has Recommendation: True");
CheckScholarshipEligibility(17, 3.6, true);
Console.WriteLine("\nTest Case 4: Age 19, GPA 3.2, Has Recommendation: True");
CheckScholarshipEligibility(19, 3.2, true);
Console.WriteLine("\nTest Case 5: Age 18, GPA 2.8, Has Recommendation: False");
CheckScholarshipEligibility(18, 2.8, false);
}
}This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Multi-dimensional Arrays
2D Arrays BasicsDeclaring and Initializing 2DAccessing 2D Array ElementsNested Loops with 2D ArraysJagged ArraysCommon Matrix OperationsRecap - Multi-dimensional4Flow Control Techniques
Early ReturnsGuard ClausesJump Statements (goto)Break and ContinueFlatten Nested Conditionals7Logical Operators Advanced
Short-Circuit EvaluationConditional Logical OperatorsOperator PrecedenceRecap - Advanced Operators2Advanced Decision Making
Multiple ConditionsComplex Boolean LogicIf vs. Switch ComparisonNested Switch StatementsRecap - Advanced Decisions5Exception Handling
Try-Catch BasicsException TypesMultiple Catch BlocksWorking with FilesFinally BlockUsing vs. Try-FinallyCustom ExceptionsRecap - Error Handling3Loop Enhancements
Loop PerformanceIterating ComplexEach Loop TypeRefactoring LoopsRecap - Optimized Loops6Null Handling
Null Reference BasicsNullable Value TypesNull Checking PatternsDefensive ProgrammingRecap - Null Safety