This commit is contained in:
ipvg 2024-07-29 21:16:58 -04:00
parent 3fbcc8d9e5
commit 5758ee7d00
2 changed files with 415 additions and 0 deletions

View File

@ -493,3 +493,360 @@ conversion
`(int)myDecimal`)
- Use the `Convert` class when you want to perform a narrowing conversion, but
want to perform rounding, not a truncation of information
---
## Exercise
### Examine the TryParse() method
When working with data, sometimes, you need to convert string data into a
numeric data type. As you learned in the previous unit, because the string data
type can hold a non-numeric value, it's possible that performing a conversion
from a `string` into a numeric data type causes a runtime error.
For example, the following code:
```cs
string name = "Bob";
Console.WriteLine(int.Parse(name));
```
Causes the following exception:
```txt
System.FormatException: 'Input string was not in a correct format.'
```
To avoid a format exception, use the TryParse() method on the target data
type.
### Use TryParse()
The TryParse() method does several things simultaneously:
- It attempts to parse a string into the given numeric data type.
- If successful, it stores the converted value in an out parameter, explained
in following section.
- It returns a `bool` to indicate whether the action succeeded or failed.
You can use the Boolean return value to take action on the value (like
performing some calculation), or display a message if the parse operation was
unsuccessful.
> Note
> In this exercise, you'll use the `int` data type, but a similar `TryParse()`
method is available on all numeric data types.
#### Out parameters
Methods can return a value or return "void" - meaning they return no value.
Methods can also return values through `out` parameters, which are defined just
like an input parameter, but include the `out` keyword.
#### TryParse() a string into an int
Delete or use the line comment operator `//` to comment out all of the code
from the previous exercises.
Update your code in the editor as follows:
```cs
string value = "102";
int result = 0;
if (int.TryParse(value, out result)) {
Console.WriteLine($"Measurement: {result}");
} else {
Console.WriteLine("Unable to report the measurement.");
}
```
Examine this line of code:
```cs
if (int.TryParse(value, out result))
```
When calling a method with an `out` parameter, you must use the keyword `out`
before the variable, which holds the value. The `out` parameter is assigned to
the `result` variable in the code `(int.TryParse(value, out result)`. You can
then use the value the `out` parameter contains throughout the rest of your
code using the variable `result`.
The `int.TryParse()` method returns `true` if it successfully converted the
`string` variable `value` into an `int`; otherwise, it returns `false`. So,
surround the statement in an `if` statement, and then perform the decision
logic, accordingly.
The converted value is stored in the `int` variable `result`. The `int`
variable `result` is declared and initialized before this line of code, so it
should be accessible both *inside* the code blocks that belong to the `if` and
`else` statements, as well as *outside* of them.
The `out` keyword instructs the compiler that the `TryParse()` method doesn't
return a value the traditional way only (as a return value), but also
communicates an output through this two-way parameter.
When you run the code, you should see the following output:
```txt
Measurement: 102
```
#### Use the parsed `int` later in code
To demonstrate that the `result` variable that was declared earlier, is
populated by the `out` parameter and is also usable later in your code, update
your code as follows:
```cs
string value = "102";
int result = 0;
if (int.TryParse(value, out result)) {
Console.WriteLine($"Measurement: {result}");
} else {
Console.WriteLine("Unable to report the measurement.");
}
Console.WriteLine($"Measurement (w/ offset): {50 + result}");
```
You should see the following output:
```txt
Measurement: 102
Measurement (w/ offset): 152
```
Examine the last line of code in the previous sample,
`Console.WriteLine($"Measurement (w/ offset): {50 + result}");`, Since the
`result` variable is defined outside of the if statement, it can be accessed
later in your code.
#### Modify the string variable to a value that can't be parsed
Lastly, look at the other scenario - where the `TryParse()` is intentionally
given a bad value that can't be converted into an int.
#### Modify the first line of code, reinitialize the variable `value` to a different value.
```cs
string value = "bad";
```
Also, modify the last line of code to ensure that the result is greater than 0
before showing the second message.
```cs
if (result > 0)
Console.WriteLine($"Measurement (w/ offset): {50 + result}");
The entire code example should now match the following code:
```
```cs
string value = "bad";
int result = 0;
if (int.TryParse(value, out result)) {
Console.WriteLine($"Measurement: {result}");
} else {
Console.WriteLine("Unable to report the measurement.");
}
if (result > 0)
Console.WriteLine($"Measurement (w/ offset): {50 + result}");
```
Save your code file, and then run your code. You should get the following
result:
```txt
Unable to report the measurement.
```
Examine the last two lines of code added in the previous sample.
```cs
if (result > 0)
Console.WriteLine($"Measurement (w/ offset): {50 + result}");
```
Since `result` is defined outside of the `if` statement, `result` can be
accessed later in your code outside of the code blocks. So then `result` can be
checked for a value greater than zero before allowing `result` + offset to be
written as output. Checking for a `result` value greater than zero avoids
printing an offset value after the `Unable to report the measurement.` message.
### Recap
The `TryParse()` method is a valuable tool. Here are few quick ideas to remember.
- Use `TryParse()` when converting a string into a numeric data type.
- `TryParse()` returns `true` if the conversion is successful, `false` if it's
unsuccessful.
- Out parameters provide a secondary means of a method returning a value. In
this case, the `out` parameter returns the converted value.
- Use the keyword `out` when passing in an argument to a method that has
defined an `out` parameter.
---
## Exercise
### Complete a challenge to combine string array values as strings and as integers
Code challenges reinforce what you've learned and help you gain some confidence
before continuing.
This module features two code challenges. This first challenge forces you to
split up the data depending on its type and either concatenate or add the data
accordingly.
> Note
> The code samples in this exercise are designed based on en-US culture setting
s, and use a period (`.`) as the decimal separator. Building and running the
code with a culture setting that uses a different decimal separators (such as a
comma `,`) may give unexpected results or errors. To fix this issue, replace
the period decimal separators in the code samples with your local decimal
separator (such as `,`). Alternatively, to run a program using the en-US
culture setting, add the following code to the top of your program:
`using System.Globalization;` and after any other `using` statements add
`CultureInfo.CurrentCulture = new CultureInfo("en-US");`.
Select and delete all code lines in the code editor. Optionally, use the line
comment operator `//` to comment out all of the code from the previous step.
To instantiate a string array, enter the following "starter" code:
```cs
string[] values = { "12.3", "45", "ABC", "11", "DEF" };
```
Create a looping structure that can be used to iterate through each string
value in the array `values`.
Complete the required code, placing it within the array looping structure code
block. It's necessary to implement the following business rules in your code
logic:
- Rule 1: If the value is alphabetical, concatenate it to form a message.
- Rule 2: If the value is numeric, add it to the total.
- Rule 3: The result should match the following output:
```txt
Message: ABCDEF
Total: 68.3
```
The Program.cs file must be saved before building or running the code.
At the Terminal command prompt, to run your code, type `dotnet run` and then
press Enter.
You should see the following output:
```txt
Message: ABCDEF
Total: 68.3
```
> Note
> If you see a message saying "Couldn't find a project to run", ensure that the Terminal command prompt displays the expected TestProject folder location. For example: C:\Users\someuser\Desktop\csharpprojects\TestProject>
Whether you get stuck and need to peek at the solution or you finish
successfully, continue to view a solution to this challenge.
---
## Exercise
### Complete a challenge to output math operations as specific number types
Here's a second chance to use what you've learned about casting and conversion
to solve a coding challenge.
The following challenge helps you to understand the implications of casting
values considering the impact of narrowing and widening conversions.
Delete or comment out all of the code from the earlier exercise
Enter the following "starter" code:
```cs
int value1 = 11;
decimal value2 = 6.2m;
float value3 = 4.3f;
// Your code here to set result1
// Hint: You need to round the result to nearest integer (don't just truncate)
Console.WriteLine($"Divide value1 by value2, display the result as an int: {result1}");
// Your code here to set result2
Console.WriteLine($"Divide value2 by value3, display the result as a decimal: {result2}");
// Your code here to set result3
Console.WriteLine($"Divide value3 by value1, display the result as a float: {result3}");
```
Replace the code comments in the starter code with your own code to solve the
challenge:
- Solve for `result1`: Divide `value1` by `value2`, display the result as an
`int`
- Solve for `result2`: Divide `value2` by `value3`, display the result as a
`decimal`
- Solve for `result3`: Divide `value3` by `value1`, display the result as a
`float`
Solve the challenge so that your output resembles:
```txt
Divide value1 by value2, display the result as an int: 2
Divide value2 by value3, display the result as a decimal: 1.4418604651162790697674418605
Divide value3 by value1, display the result as a float: 0.3909091
```
The Program.cs file must be saved before building or running the code.
At the Terminal command prompt, to run your code, type `dotnet run` and then
press Enter.
You should see the following output:
```txt
Divide value1 by value2, display the result as an int: 2
Divide value2 by value3, display the result as a decimal: 1.4418604651162790697674418605
Divide value3 by value1, display the result as a float: 0.3909091
```
---
## Summary
Your goal was to use several different techniques to change the data type of a
given value.
You used *implicit conversion*, relying on the C# compiler to perform *widening
conversions*. When the compiler was unable to perform an implicit conversion,
you used explicit conversions. You used the `ToString()` method to explicitly
convert a numeric data type into a `string`.
When you needed to perform `narrowing conversions`, you used several different
techniques. You used the casting operator `()` when the conversion could be
made safely and were willing to accept truncation of values after the decimal.
And you used the `Convert()` method when you wanted to perform a conversion and
use common rounding rules when performing a narrowing conversion.
Finally, you used the `TryParse()` methods when the conversion from a `string`
to a numeric data type could potentially result in a data type conversion
exception.
Without this wealth of options, it would be difficult to work in a typed
programming language. Fortunately, this well executed system of types,
conversion, and casting can be harnessed to build error free applications.
### Resources
- [Casting and type conversions (C# programming guide)](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/casting-and-type-conversions)
- [Built-in types (C# reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types)
- [Default values of C# types (C# reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/default-values)

View File

@ -63,3 +63,61 @@ int value_2 = Convert.ToInt32(1.5m); // converting rounds up
Console.WriteLine(value_2);
Console.WriteLine(sep);
// string name = "Bob";
// Console.WriteLine(int.Parse(name));
Console.WriteLine(sep);
string value_3 = "102";
result_1 = 0;
if (int.TryParse(value_3, out result_1)) {
Console.WriteLine($"Measurement: {result_1}");
} else {
Console.WriteLine($"Unable to report the measurement.({value_3} - {result_1})");
}
Console.WriteLine(sep);
string[] values = { "12.3", "45", "ABC", "11", "DEF" };
float total = 0.0F;
string msg = "";
foreach (string value in values) {
float temp = 0;
if (float.TryParse(value, out temp)) {
total += temp;
} else {
msg += value;
}
}
Console.WriteLine($"Message: {msg}");
Console.WriteLine($"Total: {total}");
Console.WriteLine(sep);
int value_01 = 11;
decimal value_02 = 6.2m;
float value_03 = 4.3f;
// Your code here to set result_01
// Hint: You need to round the result to nearest integer (don't just truncate)
int result_01 = Convert.ToInt32(value_01 / value_02);
Console.Write("Divide value_01 by value_02, display the result as an int: ");
Console.WriteLine($"{result_01}");
// Your code here to set result_02
decimal result_02 = value_02 / (decimal)value_03;
Console.Write($"Divide value_02 by value_03, display the result as a decimal: ");
Console.WriteLine($"{result_02}");
// Your code here to set result_03
float result_03 = value_03 / value_01;
Console.Write($"Divide value_03 by value_01, display the result as a float: ");
Console.WriteLine($"{result_03}");
string testo = "hola";
decimal test = (decimal)testo;
Console.WriteLine(test);