end 021
This commit is contained in:
parent
3fbcc8d9e5
commit
5758ee7d00
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user