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 (you can see some of those functionalities in languages like F#).

Introduction to Switch Expressions

Consider the following function:

```@page
@{
int period = GetPayrollFrequency();
double gs = GetGrossSalary();
double incomeTax = EvaluateIncomeTax(period, gs);

string strGrossSalary = \$"{gs:f}";
string strIncomeTax = \$"{incomeTax:f}";
}

@functions{
int GetPayrollFrequency()
{
int time;

/* Frequency by which the payroll is processed:");
* 1 - Weekly
* 2 - Biweekly
* 3 - Semimonthly
* 4 - Monthly */

time = 1;

return time;
}

double GetGrossSalary()
{
double sal = 1749.88;

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;
}
}

<pre>Payroll Evaluation
------------------------
Gross Salary: @strGrossSalary
Income Tax:   @strIncomeTax
========================</pre>```

In the body of the function, we declared a local variable to hold the value to return from the function. If the function is a simple one, in the previous lesson, we saw that you don't need such a local variable. You can directly return the conditional value from each case. Here is an example:

```@functions{
double EvaluateIncomeTax(int frequency, double sal)
{
switch (frequency)
{
case 1:
return 271.08 + (sal * 24 / 100);
case 2:
return 541.82 + (sal * 24 / 100);
case 3:
return 587.12 + (sal * 24 / 100);
case 4:
return 1174.12 + (sal * 24 / 100);
}
}
}```

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 keywords without parentheses. Between those keywords, type the same type of expression we have used so far in the parentheses of switch, 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, write 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:

```@page
@{
int period = 2;
double gs = 2268.93;
double incomeTax = EvaluateIncomeTax(period, gs);

string strGrossSalary = \$"{gs:f}";
string strIncomeTax = \$"{incomeTax:f}";
}

@functions{
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),
};
}
}

<pre>Payroll Evaluation
------------------------
Gross Salary: @strGrossSalary
Income Tax:   @strIncomeTax
========================</pre>```

This would produce:

```Payroll Evaluation
------------------------
Gross Salary: 2268.93
Income Tax:   1086.36
========================```

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. Here is an example:

```@page
@{
int time = 1;

string strPeriod = IdentifyPeriodOfDay(time);
}

@functions{
/* 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 */

string IdentifyPeriodOfDay(int period)
{
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";
}
}

* 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) */

{
return type switch
{
1 => "Interstate",
2 => "Federal/State Highway",
};
}
}

<pre>Traffic Tickets System
----------------------------------------------------------
Time of Day:   @strPeriod
==========================================================</pre>```

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:

```@page
@{
int period       = GetPayrollFrequency();
double gs        = GetGrossSalary();
double incomeTax = EvaluateIncomeTax(period, gs);

string strGrossSalary = \$"{gs:f}";
string strIncomeTax = \$"{incomeTax:f}";
}

@functions{
int GetPayrollFrequency()
{
int time;

/* Frequency by which the payroll is processed:");
* 1 - Weekly
* 2 - Biweekly
* 3 - Semimonthly
* 4 - Monthly */

time = 3;

return time;
}

double GetGrossSalary()
{
double sal = 1884.68;

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
};
}

<pre>Payroll Evaluation
--------------------------------
Payroll Frequency: Semimonthly
Gross Salary:      @strGrossSalary
Income Tax:        @strIncomeTax
================================</pre>```

This would produce:

```Payroll Evaluation
--------------------------------
Payroll Frequency: Semimonthly
Gross Salary:      1884.68
Income Tax:        1039.44
================================```

When Switching a Value

Introduction

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. Here is an example:

```@page
@{
double pieceworkRate = 0.50;
string coverageArea = "Unknown";

/* Areas covered
* L - Local
* M - Metropolitan
* N - Nation */
string coverage = "l";

if((coverage == "l") || (coverage == "L"))
coverageArea  = "Local";
else if((coverage == "m") || (coverage == "M"))
coverageArea = "Metropolitan";
else if((coverage == "n") || (coverage == "N"))
coverageArea = "Nation";

// Miles driven
int miles = 22;

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;

string strPieceWorkRate = \$"{pieceworkRate:f}";
string strGrosseEarning = \$"{grossEarnings:f}";
}

<pre>============================
-- Metropolitan Delivery --
----------------------------
Coverage:         @coverageArea
Miles Driven:     @miles
Piecework Rate:   @strPieceWorkRate
----------------------------
Gross Earnings:   @strGrosseEarning
============================</pre>```

This would produce:

```============================
-- Metropolitan Delivery --
----------------------------
Coverage:         Local
Miles Driven:     22
Piecework Rate:   0.46
----------------------------
Gross Earnings:   10.12
============================```

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 Learning: Ending the Lesson

• Close Microsoft Visual Studio