Matching a Pattern

Introduction

As we saw in the previous lessons, C# makes extensive use of the switch statement. Besides the way the switch keyword is used like the if...else conditional statements, C# adds some extended functionalities referred to as pattern matching.

Practical LearningPractical Learning: Processing a Switching Return

  1. Start Microsoft Visual Studio and create a new Console App named TrafficTicketsSystem2 that supports .NET 7.0 (Standard Term Support)
  2. Change the Program.cs document as follows:
    using static System.Console;
    
    string strPeriod;
    
    string IdentifyPeriodofDay()
    {
        WriteLine("Periods");
        WriteLine("1 - Monday-Friday - Night (7PM - 6AM)");
        WriteLine("2 - Monday-Friday - Morning Rush Hour (6AM - 9AM)");
        WriteLine("3 - Monday-Friday - Regular Time (9AM - 3PM)");
        WriteLine("4 - Monday-Friday - Afternoon Rush Hour (3PM - 7PM)");
        WriteLine("5 - Weekend (Saturday-Sunday) and Holidays");
        WriteLine("----------------------------------------------------------");
        Write("Period of the infraction (1-5): ");
        int period = int.Parse(ReadLine());
        
        switch (period)
        {
            case 1:
                return "Monday-Friday - Night (7PM - 6AM)";   
            case 2:
                return "Monday-Friday - Morning Rush Hour (6AM - 9AM)";
            default: // case 3:
                return "Monday-Friday - Regular Time (9AM - 3PM)";
            case 4:
                return "Monday-Friday - Afternoon Rush Hour (3PM - 7PM)";
            case 5:
                return "Weekend (Saturday-Sunday) and Holidays";    
        }
    }
    
    WriteLine("Traffic Tickets System");
    WriteLine("==========================================================");
    /* Starting here, a police officer, a government clerk, or a designated 
     * user is used an application on a computer. We want the person 
     * to make selections on the application.
     * We want to know the period during which the infraction was committed. */
    strPeriod = IdentifyPeriodofDay();
    WriteLine("==========================================================");

Introduction to Switch Expressions

Consider the following function from things we learned in previous lessons:

using static System.Console;

int GetPayrollFrequency()
{
    int time;
    
    WriteLine("Enter the information to evaluate taxes");
    WriteLine("Frequency by which the payroll is processed:");
    WriteLine("1 - Weekly");
    WriteLine("2 - Biweekly");
    WriteLine("3 - Semimonthly");
    WriteLine("4 - Monthly");
    Write("Enter Payroll Frequency: ");
    time = int.Parse(ReadLine());

    return time;
}

double GetGrossSalary()
{
    double sal;

    Write("Gross Salary:            ");
    sal = double.Parse(ReadLine());

    return sal;
}

double EvaluateIncomeTax(int frequency, double sal)
{
    double incomeTax = 0.00;

    switch (frequency)
    {
        case 1:
            incomeTax = 271.08 + (sal * 24 / 100);
            break;
        case 2:
            incomeTax = 541.82 + (sal * 24 / 100);
            break;
        case 3:
            incomeTax = 587.12 + (sal * 24 / 100);
            break;
        case 4:
            incomeTax = 1174.12 + (sal * 24 / 100);
            break;
    }

    return incomeTax;
}

WriteLine("Payroll Evaluation");
WriteLine("============================================");
int period = GetPayrollFrequency();
WriteLine("--------------------------------------------");
double gs = GetGrossSalary();
double incomeTax = EvaluateIncomeTax(period, gs);

WriteLine("============================================");
WriteLine("Payroll Evaluation");
WriteLine("--------------------------------------------");
WriteLine("Gross Salary: {0,10:n}", gs);
WriteLine("Income Tax:   {0,10:n}", incomeTax);
WriteLine("============================================");

Instead of creating individual cases in a switch statement, you can use the => operator. To proceed, instead of a switch(expression) keyword with parentheses, replace it with the following formula:

return expression switch

Start the section with the return and the switch keyword without parentheses. Between those keywords, type the same type of expression we have used so far, such as a variable. Follow the line with a body delimited by curly brackets as seen so far with any switch statement. In that body, create a section for each possible case. This time, instead of the case keyword followed by a colon, use the => operator. On the right side the => operator, right the expression that the case clause is supposed to return. End the expression with a comma and proceed with the next case. After the closing curly bracket, you must end the whole statement with a semicolon. Here is an example:

using static System.Console;

int GetPayrollFrequency()
{
    int time;
    
    WriteLine("Enter the information to evaluate taxes");
    WriteLine("Frequency by which the payroll is processed:");
    WriteLine("1 - Weekly");
    WriteLine("2 - Biweekly");
    WriteLine("3 - Semimonthly");
    WriteLine("4 - Monthly");
    Write("Enter Payroll Frequency: ");
    time = int.Parse(ReadLine());

    return time;
}

double GetGrossSalary()
{
    double sal;

    Write("Gross Salary:            ");
    sal = double.Parse(ReadLine());

    return sal;
}

double EvaluateIncomeTax(int frequency, double sal)
{
    return frequency switch
    {
        1 => 271.08 + (sal * 24 / 100),
        2 => 541.82 + (sal * 24 / 100),
        3 => 587.12 + (sal * 24 / 100),
        4 => 1174.12 + (sal * 24 / 100)
    };
}

WriteLine("Payroll Evaluation");
WriteLine("============================================");
int period = GetPayrollFrequency();
WriteLine("--------------------------------------------");
double gs = GetGrossSalary();
double incomeTax = EvaluateIncomeTax(period, gs);

WriteLine("============================================");
WriteLine("Payroll Evaluation");
WriteLine("--------------------------------------------");
WriteLine("Gross Salary:{0,20:n}", gs);
WriteLine("Income Tax:  {0,20:n}", incomeTax);
WriteLine("============================================");

Here is an example of executing the program:

Payroll Evaluation
============================================
Enter the information to evaluate taxes
Frequency by which the payroll is processed:
1 - Weekly
2 - Biweekly
3 - Semimonthly
4 - Monthly
Enter Payroll Frequency: 1
--------------------------------------------
Gross Salary:            2466.88
============================================
Payroll Evaluation
--------------------------------------------
Gross Salary:            2,466.88
Income Tax:                863.13
============================================

Press any key to close this window . . .

The Default Case of a Switch Expression

As seen in the previous lesson, a typical switch statement can lead to a situation that doesn't fit any of the addressed cases, in which case you should have a default clause. If you are creating a switch expression, to create a default clause, use the underscore operator.

Practical LearningPractical Learning: Processing Switching Returns

Simplifying a Switch Expression

In our introduction to functions, we saw that, when a function returns a value, you can simplify its body by using the => operator. This functionality is also available for a switch expression. To apply it, after the parentheses of the function, remove the curly brackets of the function, replace the return keyword by the => operator, create the whole switch section, and end the whole statement with a semicolon. Here i5 an example:

using static System.Console;

int GetPayrollFrequency()
{
    int time;
    
    WriteLine("Enter the information to evaluate taxes");
    WriteLine("Frequency by which the payroll is processed:");
    WriteLine("1 - Weekly");
    WriteLine("2 - Biweekly");
    WriteLine("3 - Semimonthly");
    WriteLine("4 - Monthly");
    Write("Enter Payroll Frequency: ");
    time = int.Parse(ReadLine());

    return time;
}

double GetGrossSalary()
{
    double sal;

    Write("Gross Salary:            ");
    sal = double.Parse(ReadLine());

    return sal;
}

double EvaluateIncomeTax(int frequency, double sal) => frequency switch
{
    1 => 271.08 + (sal * 24 / 100),
    2 => 541.82 + (sal * 24 / 100),
    3 => 587.12 + (sal * 24 / 100),
    4 => 1174.12 + (sal * 24 / 100),
    _ => 0.00
};

WriteLine("Payroll Evaluation");
WriteLine("============================================");
int period = GetPayrollFrequency();
WriteLine("--------------------------------------------");
double gs = GetGrossSalary();
double incomeTax = EvaluateIncomeTax(period, gs);

WriteLine("============================================");
WriteLine("Payroll Evaluation");
WriteLine("--------------------------------------------");
WriteLine("Gross Salary:{0,20:n}", gs);
WriteLine("Income Tax:  {0,20:n}", incomeTax);
WriteLine("============================================");

Here is an example of running the program:

Payroll Evaluation
============================================
Enter the information to evaluate taxes
Frequency by which the payroll is processed:
1 - Weekly
2 - Biweekly
3 - Semimonthly
4 - Monthly
Enter Payroll Frequency: 2
--------------------------------------------
Gross Salary:            3317.93
============================================
Payroll Evaluation
--------------------------------------------
Gross Salary:            3,317.93
Income Tax:              1,338.12
============================================

Press any key to close this window . . .

Tuples and Switch Expressions

Processing a Tuple by Case

Remember that the cases of a switch statement can process a tuple. Here is an example adapted from an example in the previous lesson:

using static System.Console;

(int number, string name, bool allowedFullTime) member;

void RegisterEmployee()
{
    WriteLine("Enter the values about the employee");
    WriteLine("----------------------------------------------------------------------------");
    Write("Employee #:                                      ");
    member.number = int.Parse(ReadLine());
    Write("Employee Name:                                   ");
    member.name = ReadLine();
    Write("Is the employee allowed to work full-time (y/n): ");
    string answer = ReadLine();

    switch (answer)
    {
        case "y" or "Y":
            member.allowedFullTime = true;
            break;
        default:
            member.allowedFullTime = false;
            break;
    }
}
WriteLine("----------------------------------------------------------------------------");

string EvaluateStatus()
{
    string conclusion;

    switch (member)
    {
        case (975_947, "Alex Miller", false):
            conclusion = "The employee is not allowed to work overtime.";
            break;
        case (283_570, "Juliana Schwartz", true):
            conclusion = "This is a full-time employee who is allowed to work overtime.";
            break;
        case (283_624, "Arturo Garcia", true):
            conclusion = "This iemployee can work full-time.";
            break;
        default:
            conclusion = "The employee is not properly identified.";
            break;
    }

    return conclusion;
}

RegisterEmployee();

WriteLine("============================================================================");
WriteLine("Fun Department Store");
WriteLine("Employee Record");
WriteLine("----------------------------------------------------------------------------");
WriteLine($"Employee #:    {member.number}");
WriteLine($"Employee Name: {member.name}");
WriteLine($"Full-Time?     {member.allowedFullTime}");
WriteLine("----------------------------------------------------------------------------");
WriteLine("Conclusion:    {0}", EvaluateStatus());
WriteLine("============================================================================");

In this code, we used a local variable to return from the function. Of course, you can make each case return its value. This can be done as follows:

(int number, string name, bool allowedFullTime) member;

string EvaluateStatus()
{
    switch (member)
    {
        case (975_947, "Alex Miller", false):
            return "The employee is not allowed to work overtime.";
        case (283_570, "Juliana Schwartz", true):
            return "This is a full-time employee who is allowed to work overtime.";
        case (283_624, "Arturo Garcia", true):
            return "This iemployee can work full-time.";
        default:
            return "The employee is not properly identified.";
    }
}

To further reduce your code, you can convert the statement into a switch expression. This can be done as follows:

string EvaluateStatus()
{
    return member switch
    {
        (975_947, "Alex Miller", false) => "The employee is not allowed to work overtime.",
        (283_570, "Juliana Schwartz", true) => "This is a full-time employee who is allowed to work overtime.",
        (283_624, "Arturo Garcia", true) => "This iemployee can work full-time.",
        _ => "The employee is not properly identified.",
    };
}

Furthermore, you can replace the return keyword combined by the curly brackets with the => operator. This can be done as follows:

using static System.Console;

(int number, string name, bool allowedFullTime) member;

void RegisterEmployee()
{
    WriteLine("Enter the values about the employee");
    WriteLine("----------------------------------------------------------------------------");
    Write("Employee #:                                      ");
    member.number = int.Parse(ReadLine());
    Write("Employee Name:                                   ");
    member.name = ReadLine();
    Write("Is the employee allowed to work full-time (y/n): ");
    string answer = ReadLine();

    switch (answer)
    {
        case "y" or "Y":
            member.allowedFullTime = true;
            break;
        default:
            member.allowedFullTime = false;
            break;
    }
}
WriteLine("----------------------------------------------------------------------------");

string EvaluateStatus() => member switch
    {
        (975_947, "Alex Miller", false) => "The employee is not allowed to work overtime.",
        (283_570, "Juliana Schwartz", true) => "This is a full-time employee who is allowed to work overtime.",
        (283_624, "Arturo Garcia", true) => "This iemployee can work full-time.",
        _ => "The employee is not properly identified.",
    };

RegisterEmployee();

WriteLine("============================================================================");
WriteLine("Fun Department Store");
WriteLine("Employee Record");
WriteLine("----------------------------------------------------------------------------");
WriteLine($"Employee #:    {member.number}");
WriteLine($"Employee Name: {member.name}");
WriteLine($"Full-Time?     {member.allowedFullTime}");
WriteLine("----------------------------------------------------------------------------");
WriteLine("Conclusion:    {0}", EvaluateStatus());
WriteLine("============================================================================");

Expressing a Tuple

Consider a function as follows (from the previous lesson):

using static System.Console;

int GetViolation()
{
    WriteLine("Type of Traffic Violation");
    WriteLine("1 - Slow Driving");
    WriteLine("2 - Fast Driving");
    WriteLine("3 - Aggressive Driving");
    WriteLine("4 - Unknown - Other");
    WriteLine("--------------------------------------");
    Write("Type of violaction (1-4):      ");
    return int.Parse(ReadLine());
}

(int abc, string xyz) Evaluate(int problem)
{
    (int a, string b) result;

    switch (problem)
    {
        case 1:
            result = (0, "Slow Driving");
            break;
        case 2:
            result = (100, "Fast Driving");
            break;
        case 3:
            result = (125, "Aggressive Driving");
            break;
        default:
            result = (50, "Unknown - Other");
            break;
    }

    return result;
}

int infraction = GetViolation();
(int ticketAmount, string reason) ticket = Evaluate(infraction);

WriteLine("Ticket Summary");
WriteLine("======================================");
WriteLine("Traffic Violation: {0}", ticket.reason);
WriteLine("Ticket Amount:     {0}", ticket.ticketAmount);

We already know that we can reduce its code by making each case return its value. Here is an example:

(int abc, string xyz) Evaluate(int problem)
{
    switch (problem)
    {
        case 1:
            return (0, "Slow Driving");
        case 2:
            return (100, "Fast Driving");
        case 3:
            return (125, "Aggressive Driving");
        default:
            return (50, "Unknown - Other");
    }
}

If the cases of the switch statement return a tuple, you can reduce the code by creating a switch expression. Here is an example:

(int abc, string xyz) Evaluate(int problem)
{
    return problem switch
    {
        1 => (0, "Slow Driving"),
        2 => (100, "Fast Driving"),
        3 => (125, "Aggressive Driving"),
        _ => (50, "Unknown - Other")
    };
}

To further reduce the code, remember that you can replace the return keyword and the curly brackets of the function with the => operator. Here is an example:

using static System.Console;

int GetViolation()
{
    WriteLine("Type of Traffic Violation");
    WriteLine("1 - Slow Driving");
    WriteLine("2 - Fast Driving");
    WriteLine("3 - Aggressive Driving");
    WriteLine("4 - Unknown - Other");
    WriteLine("--------------------------------------");
    Write("Type of violaction (1-4):      ");
    return int.Parse(ReadLine());
}

(int abc, string xyz) Evaluate(int problem) =>
    problem switch
    {
        1 => (0, "Slow Driving"),
        2 => (100, "Fast Driving"),
        3 => (125, "Aggressive Driving"),
        _ => (50, "Unknown - Other")
    };

int infraction = GetViolation();
(int ticketAmount, string reason) ticket = Evaluate(infraction);

WriteLine("Ticket Summary");
WriteLine("======================================");
WriteLine("Traffic Violation: {0}", ticket.reason);
WriteLine("Ticket Amount:     {0}", ticket.ticketAmount);

Practical LearningPractical Learning: Switching Tuples

  1. Change the document as follows:
    using static System.Console;
    
    int violation;
    int drivingSpeed;
    int postedSpeedLimit;
    
    string strPeriod;
    string strTypeOfViolation;
    (int pay, string issue) ticketIssue;
    (int amount, string name) roadIssue;
    
    string IdentifyPeriodofDay()
    {
        WriteLine("Periods");
        WriteLine("1 - Monday-Friday - Night (7PM - 6AM)");
        WriteLine("2 - Monday-Friday - Morning Rush Hour (6AM - 9AM)");
        WriteLine("3 - Monday-Friday - Regular Time (9AM - 3PM)");
        WriteLine("4 - Monday-Friday - Afternoon Rush Hour (3PM - 7PM)");
        WriteLine("5 - Weekend (Saturday-Sunday) and Holidays");
        WriteLine("----------------------------------------------------------");
        Write("Period of the infraction (1-5): ");
        int period = int.Parse(ReadLine());
        
        switch (period)
        {
            case 1:
                return "Monday-Friday - Night (7PM - 6AM)";   
            case 2:
                return "Monday-Friday - Morning Rush Hour (6AM - 9AM)";
            default: // case 3:
                return "Monday-Friday - Regular Time (9AM - 3PM)";
            case 4:
                return "Monday-Friday - Afternoon Rush Hour (3PM - 7PM)";
            case 5:
                return "Weekend (Saturday-Sunday) and Holidays";    
        }
    }
    
    string IdentifyRoadType()
    {
        WriteLine("Type of Road");
        WriteLine("1 - Interstate (Ex. I95)");
        WriteLine("2 - Federal/State Highway (Ex. US50)");
        WriteLine("3 - State Road (Ex. TN22, MD410)");
        WriteLine("4 - County/Local Road (Ex. Randolph Rd, Eusebio Ave, Abena Blvd) or Local - Unknown (Ex. Sterling Str, Garvey Court)");
        WriteLine("----------------------------------------------------------");
        Write("Type of road (1-4):             ");
        int roadType = int.Parse(ReadLine());
    
        return roadType switch
        {
            1 => "Interstate",
            2 => "Federal/State Highway",
            3 => "State Road",
            _ => "County/Local Road, Others"
        };
    }
    
    (int a, string b) IdentifyTrafficIssue()
    {
        WriteLine("Types of issues");
        WriteLine("0 - No particular issues");
        WriteLine("1 - Health issues");
        WriteLine("2 - Driving while sleeping");
        WriteLine("3 - Driving while using an electronic device");
        WriteLine("4 - Driving under the influence (of alcohol, drugs, intoxicating products, etc)");
        Write("Type of issue (0-4):            ");
        int typeOfIssue = int.Parse(ReadLine());
        
        switch(typeOfIssue)
        {
            case 1:
                return (0, "Health issues");
            case 2:
                return (150, "Driving while sleeping");
            case 3:
                return (100, "Driving while using an electronic device");
            case 4:
                return (350, "Driving under the influence (alcohol, drugs, intoxicating products, or else)");
            default:
                return (0, "No particular issues relatted to the traffic violation");
        }
    }
    
    (int a, string b) EvaluateInterstateTraffic()
    {
        WriteLine("Type of Traffic Violation");
        WriteLine("1 - Slow Driving");
        WriteLine("2 - Fast Driving");
        WriteLine("3 - Aggressive Driving");
        WriteLine("4 - Unknown - Other");
        WriteLine("----------------------------------------------------------");
        Write("Type of violaction (1-4):      ");
        violation = int.Parse(ReadLine());
    
        switch (violation)
        {
            case 1:
                return (0, "Slow Driving");
            case 2:
                return (100, "Fast Driving");
            case 3:
                return (125, "Aggressive Driving");
            default:
                return (50, "Unknown - Other");
        }
    }
    
    (int a, string b) EvaluateHighwayTraffic()
    {
        WriteLine("Type of Traffic Violation");
        WriteLine("1 - Slow Driving");
        WriteLine("2 - Fast Driving");
        WriteLine("3 - Aggressive Driving");
        WriteLine("4 - Driving Through Steady Red Light");
        WriteLine("5 - Driving Through Flashing Red Light");
        WriteLine("6 - Red Light Right Turn Without Stopping");
        WriteLine("7 - Unknown - Other");
        WriteLine("----------------------------------------------------------");
        Write("Type of violaction (1-7):      ");
        violation = int.Parse(ReadLine());
    
        return violation switch
        {
            1 => (0, "Slow Driving"),
            2 => (65, "Fast Driving"),
            3 => (75, "Aggressive Driving"),
            4 => (105, "Driving Through Steady Red Light"),
            5 => (35, "Driving Through Flashing Red Light"),
            6 => (25, "Red Light Right Turn Without Stopping"),
            _ => (5, "Unknown - Other")
        };
    }
    
    (int a, string b) EvaluateLocalTraffic()
    {
        WriteLine("Type of Traffic Violation");
        WriteLine("1 - Slow Driving");
        WriteLine("2 - Fast Driving");
        WriteLine("3 - Aggressive Driving");
        WriteLine("4 - Driving Through Steady Red Light");
        WriteLine("5 - Driving Through Flashing Red Light");
        WriteLine("6 - Red Light Right Turn Without Stopping");
        WriteLine("7 - Driving Through Stop Sign Without Stopping");
        WriteLine("8 - Unknown - Other");
        WriteLine("----------------------------------------------------------");
        Write("Type of violaction (1-8):      ");
        violation = int.Parse(ReadLine());
    
        return violation switch
        {
            1 => ( 0, "Slow Driving"),
            2 => (35, "Fast Driving"),
            3 => (55, "Aggressive Driving"),
            4 => (65, "Driving Through Steady Red Light"),
            5 => (55, "Driving Through Flashing Red Light"),
            6 => (35, "Red Light Right Turn Without Stopping"),
            7 => (15, "Driving Through Stop Sign Without Stopping"),
            _ => ( 5, "Unknown - Other")
        };
    }
    
    WriteLine("Traffic System System");
    WriteLine("==========================================================");
    strPeriod = IdentifyPeriodofDay();
    WriteLine("==========================================================");
    string strRoadType = IdentifyRoadType();
    WriteLine("==========================================================");
    
    Write("Posted Speed Limit:             ");
    postedSpeedLimit = int.Parse(ReadLine());
    Write("Driving Speed:                  ");
    drivingSpeed = int.Parse(ReadLine());
    WriteLine("==========================================================");
    ticketIssue = IdentifyTrafficIssue();
    WriteLine("==========================================================");
    
    if (strRoadType == "Interstate")
    {
        roadIssue = EvaluateInterstateTraffic();
    }
    else if (strRoadType == "Federal/State Highway")
    {
        roadIssue = EvaluateHighwayTraffic();
    }
    else
    {
        roadIssue = EvaluateLocalTraffic();
    }
    
    WriteLine("==========================================================");
    WriteLine("Traffic Ticket Summary");
    WriteLine("----------------------------------------------------------");
    WriteLine("Period of the day:  {0}", strPeriod);
    WriteLine("Road Type:          {0}", strRoadType);
    WriteLine("Posted Speed Limit: {0}", postedSpeedLimit);
    WriteLine("Driving Speed:      {0}", drivingSpeed);
    WriteLine("Type of Issue:      {0}", ticketIssue.issue);
    WriteLine("     Base Ticket:   {0}", ticketIssue.pay);
    WriteLine("Violation Type:     {0}", roadIssue.name);
    WriteLine("     Addition Fee:  {0}", roadIssue.amount);
    WriteLine("----------------------------------------------------------");
    WriteLine("Ticket Amount:      {0}", ticketIssue.pay + roadIssue.amount);
    WriteLine("==========================================================");
  2. To execute the application, on the main menu, click Debug -> Start Without Debugging
  3. When requested, type the values as follows and press Enter after each:
    Periods:            2
    Type of Road:       1
    Posted Speed Limit: 55
    Driving Speed:      85
    Type of Issue:      3
    Type of Violation:  3
    ---------------------------
    Traffic System System
    ==========================================================
    Periods
    1 - Monday-Friday - Night (7PM - 6AM)
    2 - Monday-Friday - Morning Rush Hour (6AM - 9AM)
    3 - Monday-Friday - Regular Time (9AM - 3PM)
    4 - Monday-Friday - Afternoon Rush Hour (3PM - 7PM)
    5 - Weekend (Saturday-Sunday) and Holidays
    ----------------------------------------------------------
    Period of the infraction (1-5): 2
    ==========================================================
    Type of Road
    1 - Interstate (Ex. I95)
    2 - Federal/State Highway (Ex. US50)
    3 - State Road (Ex. TN22, MD410)
    4 - County/Local Road (Ex. Randolph Rd, Eusebio Ave, Abena Blvd) or Local - Unknown (Ex. Sterling Str, Garvey Court)
    ----------------------------------------------------------
    Type of road (1-4):             1
    ==========================================================
    Posted Speed Limit:             55
    Driving Speed:                  85
    ==========================================================
    Types of issues
    0 - No particular issues
    1 - Health issues
    2 - Driving while sleeping
    3 - Driving while using an electronic device
    4 - Driving under the influence (of alcohol, drugs, intoxicating products, etc)
    Type of issue (0-4):            3
    ==========================================================
    Type of Traffic Violation
    1 - Slow Driving
    2 - Fast Driving
    3 - Aggressive Driving
    4 - Unknown - Other
    ----------------------------------------------------------
    Type of violaction (1-4):      3
    ==========================================================
    Traffic Ticket Summary
    ----------------------------------------------------------
    Period of the day:  Monday-Friday - Morning Rush Hour (6AM - 9AM)
    Road Type:          Interstate
    Posted Speed Limit: 55
    Driving Speed:      85
    Type of Issue:      Driving while using an electronic device
         Base Ticket:   100
    Violation Type:     Aggressive Driving
         Addition Fee:  125
    ----------------------------------------------------------
    Ticket Amount:      225
    ==========================================================
    
    Press any key to close this window . . .

Pattern Matching

When Switching a Value

So far, we have seen that, when you are setting up a switch statement, create the desired case clauses in the switch section. The case keyword can be followed by either a constant value or an expression. Here are examples:

switch (number)
{
    case 1:
        selected = h;
        break;
    case 2:
        selected = he;
        break;
    case 3:
        selected = li;
        break;
}

Pattern matching consists of applying a condition to a case. In a case of a switch statement, you can include a conditional statement that compares its value to another to actually validate the case. This is done using the when keyword. The formula to follow is:

case value-or-expression when logical-expression: statement(s)

As mentioned already, the case is followed by a constant or an expression, The new keyword is when. It is followed by a logical expression.

We are starting a sample application named "Metropolitan Delivery". It is a (fictitious) company that owns various types of vehicles that are used by employees to deliver various types of merchandise. The pay of the employees is based on various factors. The deliveries made by the company are in three categories. The local covered includes the neighborhoods commonly known by employees and the ZIP codes are those close to the company's location. The metropolitan coverage is also an area familiar to the employees, including the cities in the proximity of less than 200 miles of the company's location. Any area beyond that distance is considered as nationwide. The employees are paid on the distance they cover to deliver a merchandise, but the rate depends on the category of coverage.

Practical LearningPractical Learning: When Switching a Value

  1. Change the document as follows:
    using static System.Console;
    
    double pieceworkRate = 0.50;
    string coverageArea = "Unknown";
    
    WriteLine("================================");
    WriteLine("-- Metropolitan Delivery --");
    WriteLine("================================");
    WriteLine("Areas covered");
    WriteLine("L - Local");
    WriteLine("M - Metropolitan");
    WriteLine("N - Nation");
    Write("Enter the covered area: ");
    string coverage = ReadLine();
    
    if((coverage == "l") || (coverage == "L"))
        coverageArea  = "Local";
    else if((coverage == "m") || (coverage == "M"))
        coverageArea = "Metropolitan";
    else if((coverage == "n") || (coverage == "N"))
        coverageArea = "Nation";
    
    Write("Miles driven:           ");
    int miles = int.Parse(ReadLine());
    
    switch(coverageArea)
    {
        case "Local" when miles < 25:
            pieceworkRate = .46;
            break;
        case "Local" when miles >= 25 && miles < 65:
            pieceworkRate = .62;
            break;
        case "Local" when miles >= 65:
            pieceworkRate = .88;
            break;
        case "Metro":
            pieceworkRate = 1.42;
            break;
        case "Nation":
            pieceworkRate = 1.57;
            break;
    }
    
    double grossEarnings = miles * pieceworkRate;
    
    WriteLine("================================");
    WriteLine("-- Metropolitan Delivery --");
    WriteLine("================================");
    WriteLine($"Coverage:       {coverageArea}");
    WriteLine($"Miles Driven:   {miles,8}");
    WriteLine($"Piecework Rate: {pieceworkRate,8:f}");
    WriteLine($"Gross Earnings: {grossEarnings,8:f}");
    WriteLine("================================");
  2. To execute the application, on the main menu, click Debug -> Start Without Debugging
  3. When requested, for the Covered Area, type l and press Enter
  4. For the Miles Driven, type 22 and press Enter
    ================================
    -- Metropolitan Delivery --
    ================================
    Areas covered
    L - Local
    M - Metropolitan
    N - Nation
    Enter the covered area: l
    Miles driven:           22
    ================================
    -- Metropolitan Delivery --
    ================================
    Coverage:       Local
    Miles Driven:         22
    Piecework Rate:     0.46
    Gross Earnings:    10.12
    ================================
    Press any key to close this window . . .
  5. Press Enter to close the window and return to your programming environment
  6. To execute again, on the main menu, click Debug -> Start Without Debugging
  7. When requested, for the Covered Area, type L and press Enter
  8. For the Miles Driven, type 46 and press Enter
    ================================
    -- Metropolitan Delivery --
    ================================
    Areas covered
    L - Local
    M - Metropolitan
    N - Nation
    Enter the covered area: L
    Miles driven:           46
    ================================
    -- Metropolitan Delivery --
    ================================
    Coverage:       Local
    Miles Driven:         46
    Piecework Rate:     0.62
    Gross Earnings:    28.52
    ================================
    Press any key to close this window . . .
  9. Press Enter to close the window and return to your programming environment
  10. To execute again, on the main menu, click Debug -> Start Without Debugging
  11. When requested, for the Covered Area, type L and press Enter
  12. For the Miles Driven, type 148 and press Enter
    ================================
    -- Metropolitan Delivery --
    ================================
    Areas covered
    L - Local
    M - Metropolitan
    N - Nation
    Enter the covered area: L
    Miles driven:           148
    ================================
    -- Metropolitan Delivery --
    ================================
    Coverage:       Local
    Miles Driven:        148
    Piecework Rate:     0.88
    Gross Earnings:   130.24
    ================================
    Press any key to close this window . . .
  13. Press Enter to close the window and return to your programming environment
  14. To execute again, on the main menu, click Debug -> Start Without Debugging
  15. When requested, for the Covered Area, type n and press Enter
  16. For the Miles Driven, type 148 and press Enter
    ================================
    -- Metropolitan Delivery --
    ================================
    Areas covered
    L - Local
    M - Metropolitan
    N - Nation
    Enter the covered area: n
    Miles driven:           148
    ================================
    -- Metropolitan Delivery --
    ================================
    Coverage:       Nation
    Miles Driven:        148
    Piecework Rate:     1.57
    Gross Earnings:   232.36
    ================================
    Press any key to close this window . . .
  17. Press Enter to close the window and return to your programming environment

When Switching a Variable

After a case keyword, you can declare a variable of the same type as the value used in the parentheses of switch(). Follow the variable with the when keyword followed by a logical expression that equates the variable to the case value. The variable is "visible" only with its case. Therefore, you can use the same variable in different case sections.

When Patterning a Conditional Statement

The when expression is used to apply a conditional statement. It can consist of an expression that uses any of the Boolean operators we are familiar with. It may look as follows:

switch(number)
{
    case value-or-expression when number > 8:
        statement(s);
        break;
}

Patterning Different Types of Values

When using a switch statement, the values involved must be of the same type or compatible. Otherwise, you can find a way to convert them.

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2001-2023, FunctionX Saturday 29 April 2023, 23:36 Next