Chapter 4: Writing, Debugging, and Testing Functions [Flashcarder]

(177 cards)

1
Q

What is a fundamental principle of programming mentioned in the book?

A

Don’t Repeat Yourself (DRY).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What should you do if you find yourself writing the same statements over and over again while programming?

A

Turn those statements into a function.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

How are functions described in the book?

A

Functions are like tiny programs that complete one small task, usually having inputs and outputs.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What feature was introduced with C# 9 and is used by the default project template for console apps since C# 10 and .NET 6?

A

The top-level program feature.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

How do functions work with the automatically generated Program class and its <Main>$ method in top-level programs?

A

Functions defined in top-level programs become local functions within the <Main>$ method of the Program class.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is the suggested practice for the placement of functions in a file?

A

Functions should be placed at the bottom of the file rather than mixed with other top-level statements.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What compiler error occurs if types like classes are declared in the middle of the Program.cs file?

A

Compiler error CS8803.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What does the compiler automatically generate for a local function in C#?

A

The compiler generates an inner method within the existing method or function, making it local to that context.

If the local function is within the Main method of the Program class, it remains nested inside that method, without creating a new class or method.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Where must import statements (using) be placed in the Program.cs file?

A

Import statements must go at the top of the Program.cs file.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Where can statements that go into the <Main>$ function be placed in the Program.cs file?

A

Statements that will go in the <Main>$ function can be mixed with functions in the middle of the Program.cs file. Any functions will become local functions in the <Main>$ method.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Why can’t local functions have XML comments?

A

Local functions cannot have XML comments because they cannot be used outside the member in which they are declared.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What is a better approach than defining functions within the Program.cs file?

A

A better approach is to write any functions in a separate file and define them as static members of the Program class.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What should you name a new class file for defining functions as static members of the Program class?

A

The name of the file does not actually matter, but using a naming convention like Program.Functions.cs is sensible.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What happens when you define a partial Program class with static functions in a separate file?

A

The compiler defines a Program class with a <Main>$ function and merges your function as a member of the Program class.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Why should you not define a namespace for your partial Program class?

A

If you define a namespace for your partial Program class, it will be in a different namespace and will not merge with the auto-generated partial Program class.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

What is the strict definition of a parameter in a function?

A

A parameter is a variable in a function definition.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Provide an example of a function with a parameter.

A
void Hire(DateTime startDate) 
{
    // Function implementation.
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

What is the strict definition of an argument in a function call?

A

An argument is the data you pass into the method’s parameters when a method is called.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Provide an example of passing an argument to a function.

A
DateTime when = new(year: 2024, month: 11, day: 5);
Hire(when);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

How can you specify the parameter name when passing an argument?

A

You can specify the parameter name by using named arguments.
For example, MyMethod(paramName: value);

DateTime when = new(year: 2024, month: 11, day: 5);
Hire(startDate: when);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

What terms do the official Microsoft documentation use interchangeably?

A

Named and optional arguments and
named and optional parameters.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

How can a single object act as both a parameter and an argument?

A

Within a function implementation, a parameter can be passed as an argument to another function.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

Provide an example where a parameter is passed as an argument to another function.

A
void Hire(DateTime startDate)
{
    ...
    SaveToDatabase(startDate, employeeRecord);
    ...
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

What is a classic example of naming a parameter in C#?

A

The parameter named args in the Main function.

static void Main(String[] args)
{
    ...
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Summarize the **difference between parameters and arguments**.
**Parameters *define* inputs to a function.** **Arguments are *passed* to a function when calling the function.**
26
What is a **good practice** when using the **terms parameter and argument**?
Try to **use the correct term depending on the context**, but do not get pedantic with other developers if they “misuse” a term.
27
What are **cardinal numbers**?
Cardinal numbers are **numbers used to count**, for example, 1, 2, and 3.
28
What are **ordinal numbers**?
Ordinal numbers are **numbers used to order**, for example, 1st, 2nd, and 3rd.
29
How is the **factorial** of a number calculated?
The factorial is calculated by **multiplying the number by each of the positive integers less than it until reaching 1**. For example, the factorial of 5 is 5 x 4 x 3 x 2 x 1 = 120.
30
What is the **factorial of 0**?
**0! = 1**
31
Provide the **definition of a factorial for a positive integer n**.
**n! = n × (n − 1)!, for n ∈ { 1, 2, 3, ... }**
32
How is a **negative number handled in the Factorial function**?
The function **throws an *ArgumentOutOfRangeException***.
33
What **value** does the **Factorial function** return when the **input is 0**?
The function **returns 1.**
34
Provide the **implementation of the Factorial function.**
``` static int Factorial(int number) { if (number < 0) { throw new ArgumentOutOfRangeException(message: $"The factorial function is defined for non-negative integers only. Input: {number}", paramName: nameof(number)); } else if (number == 0) { return 1; } else { return number * Factorial(number - 1); } } ```
35
What is **recursion** in the context of the *Factorial* function?
***Recursion* is a technique where a function calls itself within its implementation.**
36
What are some **potential problems with recursion** mentioned in the text?
Recursion can lead to problems such as **stack overflow** due to **too many function calls** because memory is used to store data on every function call.
37
What is an **alternative to recursion** that is mentioned as more practical in C#?
**Iteration** is a more *practical* solution than recursion in C#.
38
Why do **factorials of 13 and higher overflow the *int*** type?
Factorials of 13 and higher overflow the int type because they **exceed the maximum positive value that can be stored in a 32-bit integer**, which is *about 2 billion*.
39
How can you modify the Factorial function to **check for overflows**?
Use the ***checked* keyword** in the statement that calls itself: ``` checked { return number * Factorial(number - 1); } ```
40
How can the **RunFactorial function** be modified to **handle overflow** and other exceptions?
``` static void RunFactorial() { for (int i = -2; i <= 15; i++) { try { WriteLine($"{i}! = {Factorial(i):N0}"); } catch (OverflowException) { WriteLine($"{i}! is too big for a 32-bit integer."); } catch (Exception ex) { WriteLine($"{i}! throws {ex.GetType()}: {ex.Message}"); } } } ```
41
What is the **output of the modified RunFactorial function** for numbers -2 to 15?
``` -2! throws System.ArgumentOutOfRangeException: The factorial function is defined for non-negative integers only. Input: -2 (Parameter 'number') -1! throws System.ArgumentOutOfRangeException: The factorial function is defined for non-negative integers only. Input: -1 (Parameter 'number') 0! = 1 1! = 1 2! = 2 ... 12! = 479,001,600 13! is too big for a 32-bit integer. 14! is too big for a 32-bit integer. 15! is too big for a 32-bit integer. ```
42
What is **shown by default** when **calling a function** in a code editor?
A **tooltip** with *basic* information is shown by default.
43
How can you **improve the tooltip information** in Visual Studio Code?
1.**Customize Tooltip Settings:** * Adjust font size and color for better readability in **Settings** > **Editor**: **Tooltip Font Size** and **Editor: Tooltip Color**. * Enable or disable specific tooltips by searching for **tooltip** in the settings (Ctrl+,) and customizing preferences. 2.**Install Extensions:** Use IntelliSense extensions like ***IntelliSense for CSS class names in HTML***, ***Path Intellisense***, and language-specific extensions to enhance the detail and relevance of tooltip information. 3.**Use Settings Sync:** * Sync your customized settings across different devices using Visual Studio Code's **Settings Sync** feature. 4.**Edit Settings JSON:** * Manually tweak tooltip settings in **settings.json** for more precise control.
44
What happens when you type **3 forward slashes (///) above a function** in Visual Studio?
It **expands into an XML comment** template.
45
What is the primary **purpose of XML documentation** comments?
To be used with **tools** that **convert the comments into documentation**, like ***Sandcastle***.
46
Why don't **local functions** support **XML comments**?
Because **local functions cannot be used outside the member in which they are declared**, making it unnecessary to generate documentation for them.
47
What is the **recommended practice for adding XML documentation** comments?
**Add XML documentation comments to all your functions *except* local functions.**
48
What is **F#**?
F# is Microsoft’s **strongly typed functional-first programming language** that compiles to **Intermediate Language (IL)** to be executed by **.NET**.
49
What are some important **attributes of functional languages**?
1.**Modularity**: Breaks up a large complex code base into smaller pieces. 2.**Immutability**: Variables do not exist in the traditional sense, reducing bugs. 3.**Maintainability**: Code is cleaner and clearer (for mathematically-inclined programmers).
50
What are some **features added to C#** to support a more functional approach?
**Tuples** and **pattern matching** in *C# 7*. **Non-null reference types** in *C# 8*. **Improved pattern matching** and **adding records** in *C# 9.*
51
What is an **expression-bodied function member** in C#?
A concise **syntax for defining methods and properties using the => character to indicate a *return* value.**
52
What is the **Fibonacci** sequence?
A **sequence of numbers starting with 0 and 1, where each subsequent number is the sum of the previous two numbers**.
53
Provide the **implementation of the FibImperative function**.
``` static int FibImperative(uint term) { if (term == 0) { throw new ArgumentOutOfRangeException(); } else if (term == 1) { return 0; } else if (term == 2) { return 1; } else { return FibImperative(term - 1) + FibImperative(term - 2); } } ```
54
What does the **FibImperative function** do?
It **calculates the Fibonacci sequence in an *imperative* style**, using **if-else** statements and **recursion**.
55
Provide the **implementation of the RunFibImperative function.**
``` static void RunFibImperative() { for (uint i = 1; i <= 30; i++) { WriteLine("The {0} term of the Fibonacci sequence is {1:N0}.", arg0: CardinalToOrdinal(i), arg1: FibImperative(term: i)); } } ```
56
What is the **output of the RunFibImperative function** for the first 5 terms of the Fibonacci sequence?
``` The 1st term of the Fibonacci sequence is 0. The 2nd term of the Fibonacci sequence is 1. The 3rd term of the Fibonacci sequence is 1. The 4th term of the Fibonacci sequence is 2. The 5th term of the Fibonacci sequence is 3. ```
57
Provide the **implementation of the FibFunctional function**.
``` static int FibFunctional(uint term) => term switch { 0 => throw new ArgumentOutOfRangeException(), 1 => 0, 2 => 1, _ => FibFunctional(term - 1) + FibFunctional(term - 2) }; ```
58
What does the **FibFunctional function** do?
It calculates the **Fibonacci sequence in a *declarative* style** using a **switch** expression and **recursion**.
59
Provide the **implementation of the RunFibFunctional** function.
``` static void RunFibFunctional() { for (uint i = 1; i <= 30; i++) { WriteLine("The {0} term of the Fibonacci sequence is {1:N0}.", arg0: CardinalToOrdinal(i), arg1: FibFunctional(term: i)); } } ```
60
What will be the result of **running the RunFibFunctional function**?
The result will be the **same as the RunFibImperative function**, **displaying the first 30 terms of the Fibonacci** sequence.
61
What is the main **difference between FibImperative and FibFunctional functions**?
**FibImperative** is written in an ***imperative*** style using **if-else** statements, while **FibFunctional** is written in a ***declarative*** style using a **switch** expression.
62
What type of **code editor** must you use to **debug** problems at development time?
You must use a code editor that has **debugging tools**, such as *Visual Studio 2022* or *Visual Studio Code*.
63
What is a **breakpoint**?
A breakpoint is a **marker set on a line of code where the debugger will pause execution**, allowing you to inspect the program state and find bugs.
64
How do you **set a breakpoint** in Visual Studio Code?
1. **Click on the line** where you want to set the breakpoint. 1. Navigate to Run | Toggle Breakpoint or **press F9**. 1. A **red circle** will appear in the margin bar to indicate the breakpoint.
65
How do you **start debugging** in Visual Studio Code?
1. Navigate to View | Run, or **click the *Run and Debug*** icon, or press Ctrl + Shift + D. 1. Click the ***Run and Debug* button** at the top of the RUN AND **DEBUG** window. 1. Select the **Debugging project**. 1. Visual Studio Code will **start the console app** and **pause at the breakpoint**.
66
What is **break mode** in Visual Studio Code?
Break mode is when the **debugger pauses execution at a breakpoin**t, highlighting the next line to be executed in yellow, and allowing inspection of the program state.
67
What are some **common buttons** in the debugging toolbar?
* **Start/Continue/F5**: Starts or continues running the project. * **Hot Reload**: Reloads compiled code changes without restarting the app. * **Break All**: Breaks into the next available line of code. * **Stop Debugging/Stop/Shift + F5**: Stops the debugging session. * **Restart/Ctrl or Cmd + Shift + F5**: Stops and restarts the program with the debugger attached. * **Show Next Statement**: Moves the cursor to the next statement to be executed. * **Step Into/F11**: Steps into the code statements. * **Step Over/F10**: Steps over the code statements. * **Step Out/Shift + F11**: Steps out of the current function. * **Show Threads in Source**: Examines and works with threads in the application.
68
What are some of the **most useful debugging windows** in Visual Studio and Visual Studio Code?
* **VARIABLES**: Shows the name, value, and type of any local variables. * **WATCH**: Shows the value of variables and expressions that you manually enter. * **CALL STACK**: Shows the stack of function calls. * **BREAKPOINTS**: Shows all your breakpoints and allows finer control over them. * **DEBUG CONSOLE or Immediate Window**: Enables live interaction with your code.
69
How can you **step into code** using Visual Studio 2022 or Visual Studio Code?
Navigate to **Run or Debug | Step Into**, click on the ***Step Into* button** in the toolbar, or **press F11**.
70
What does the **Step Over** command do during debugging?
Step Over (F10) **executes the next line of code, skipping over the method calls** without stepping into them.
71
What is the **difference between *Step Into* and *Step Over*** ?
***Step Into* steps into the method to allow you to debug each line** within it, while ***Step Over* executes the entire method** in one go.
72
How do you **add an expression to the WATCH window** in Visual Studio or Visual Studio Code?
**Select the expression in the code, right-click it, and select Add to Watch or Add Watch.**
73
How do you **change the console to use the integrated terminal** in Visual Studio Code?
**Modify the *launch.json* file to change the console setting from *internalConsole* to *integratedTerminal*.**
74
How do you **create a launch configuration for a .NET Core Console App** in Visual Studio Code?
1. Click the create a **launch.json** file link. 1. Select **C#** for the debugger. 1. Click the **Add Configuration** button. 1. Select **.NET: Launch .NET Core Console App.** 1. **Modify the launch.json** file with the correct settings.
75
How do you **set a conditional breakpoint** in Visual Studio Code or Visual Studio 2022?
**Right-click the breakpoint** and **choose Edit Breakpoint** (Visual Studio Code) or Conditions (Visual Studio 2022), then **enter the expression** that must evaluate to *true* for the breakpoint to activate.
76
What does the ***Hit Count* option** do for **breakpoints**?
Hit Count **specifies the number of times the breakpoint must be hit before it activates.**
77
How can you **interact with your code** using the **DEBUG CONSOLE or Immediate Window**?
You **can enter commands or expressions** to interrogate the program state, such as evaluating the value of variables or performing calculations.
78
What **steps** should you follow to **debug a console app** using Visual Studio Code?
1. Set a **breakpoint**. 1. Click the **Run and Debug** button. 1. Select the **Debugging project**. 1. Step through the code using **Step Into (F11)** or **Step Over (F10)**. 1. **Fix any bugs** and **restart debugging**.
79
What is **Hot Reload**?
Hot Reload is a feature that allows a developer to **apply changes to code while the app is running and immediately see the effect.** It is also known as **Edit and Continue.**
80
How do you **start a console app with Hot Reload** using Visual Studio Code?
In the **TERMINAL**, start the console app using the `dotnet watch` command.
81
What happens when you **change the message** in the console app and **Hot Reload is active**?
The **change is applied after a couple of seconds without needing to restart** the console app.
82
How do you **stop the console app running with Hot Reload**?
**Press *Ctrl + C* to stop it running.**
83
Why is it **important to log events and data** during *runtime*?
Because ***end users* are notoriously *bad* at accurately describing what they were doing when an error occurred**, making it difficult to reproduce and fix the problem without logs.
84
What is a **good practice** mentioned for **logging**?
**Add code throughout your application to log what is happening**, especially when **exceptions** occur, so that you can **review the logs** and use them to **trace and fix issues**.
85
What are some **common third-party logging frameworks** mentioned?
* **Apache log4net** * **NLog** * **Serilog**
86
What is the **difference between the *Debug* and *Trace* classes** in .NET?
The ***Debug* class** is used to **add logging** that gets written only during **development**. The ***Trace* class** is used to **add logging** that gets written during **both development and runtime**.
87
What is a **trace listener** in .NET?
A trace listener is a **type that can be configured to write output anywhere you like when the *WriteLine* method is called**.
88
How do you **write messages** using ***Debug* and *Trace* classes**?
``` Debug.WriteLine("Debug says, I am watching!"); Trace.WriteLine("Trace says, I am watching!"); ```
89
Why should you **enable *AutoFlush* only during debugging** and *not in production*?
Enabling ***AutoFlush*** **reduces performance** because it calls the *Flush* method after every write. This behavior is **useful during debugging** to see immediate results but should **not be used in production.**
90
What happens when you **run the release configuration of the console app with trace listeners configured**?
**Only the *Trace* messages will be written to the *trace listeners*.**
91
What happens when you **run the debug configuration of the console app with *trace listeners* configured**?
**Both *Debug* and *Trace* messages will be written to the *trace listeners*.**
92
How can you add **statements to flush and close any *buffered trace listeners*** for ***Debug*** and ***Trace***?
``` Debug.Close(); Trace.Close(); ```
93
How do you **start the Instrumenting project with debugging** in Visual Studio Code?
Enter the following **command** in the **TERMINAL** window: `dotnet run --configuration Debug`
94
What is the **benefit of using *Debug.WriteLine* calls** throughout your code?
They **will be stripped out automatically when you build the *release version* of your application**, ensuring they do not affect performance.
95
What are the **possible trace levels** that can be set using a **trace switch**?
* **Off (0)**: Outputs *nothing*. * **Error (1)**: Outputs *only errors.* * **Warning (2)**: Outputs e*rrors and warnings.* * **Info (3)**: Outputs *errors, warnings, and information.* * **Verbose (4)**: Outputs *all levels.*
96
How can you **set the value of a trace switch**?
The value of a trace switch can be set **using a number or a corresponding word**, for example, using the number 3 or the word "Info".
97
What does **setting a trace switch to "Verbose"** do?
It **outputs all levels,** including **errors**, **warnings**, **information**, and **verbose messages**.
98
How do you **add the *Microsoft.Extensions.Configuration.Binder*** and ***Microsoft.Extensions.Configuration.Json*** **NuGet packages** to a project in Visual Studio Code?
``` dotnet add package Microsoft.Extensions.Configuration.Binder dotnet add package Microsoft.Extensions.Configuration.Json ```
99
What is the **difference between *dotnet add package*** and ***dotnet add reference*** commands?
***dotnet add package*** **adds a reference to a NuGet package** to your project file, which will be *downloaded during the build* process. ***dotnet add reference*** **adds a project-to-project reference** to your project file, and the *referenced project will be compiled if needed during the build process*.
100
Why is it **useful to have fine control over trace output**?
It allows you to **control the verbosity of the logging output**, making it **easier to debug and monitor** applications without overwhelming the log files with unnecessary information.
101
What should you do if you encounter **unexpected issues with a NuGet package**?
**Try using an earlier version** of the package.
102
How do you **define a setting named *PacktSwitch* with a value of *Info* in appsettings.json**?
``` { "PacktSwitch": { "Value": "Info" } } ```
103
What **configuration** is needed to **copy *appsettings.json* to the output directory** in Visual Studio?
Set the ***Copy to Output Directory*** property of appsettings.json to ***Copy if newer*** or ***Copy always***.
104
Provide the **project file element** that ensures ***appsettings.json* is copied to the output directory**.
``` Always ```
105
How do you **output the 4 trace switch levels** in C#?
``` Trace.WriteLineIf(ts.TraceError, "Trace error"); Trace.WriteLineIf(ts.TraceWarning, "Trace warning"); Trace.WriteLineIf(ts.TraceInfo, "Trace information"); Trace.WriteLineIf(ts.TraceVerbose, "Trace verbose"); ```
106
How do you **ensure *Debug* and *Trace* are not closed prematurely** in your code?
**Do not close *Debug* or *Trace* before you are done using them**. If you close them and then write to them, nothing will happen.
107
How do you **modify appsettings.json to set a level value of *Warning***?
``` { "PacktSwitch": { "Value": "2" } } ```
108
What is the **purpose of *logging* the name of the source code file, the method, and the line number**?
Logging this information **helps in debugging** by providing context about **where a particular log entry was generated in the source code**.
109
What **special attributes** in C# can be used to **get information about the method caller**?
``` [CallerMemberName] [CallerFilePath] [CallerLineNumber] [CallerArgumentExpression] ```
110
What does the `[CallerMemberName]` attribute do?
It **sets the string parameter to the *name of the method or property*** that is executing the method that defines this parameter.
111
What does the `[CallerFilePath]` attribute do?
It **sets the string parameter to the *name of the source code file*** that contains the statement that is executing the method that defines this parameter.
112
What does the `[CallerLineNumber]` attribute do?
It **sets the int parameter to the line number in the source code file of the statement** that is executing the method that defines this parameter.
113
What does the `[CallerArgumentExpression]` attribute do?
It **sets the string parameter to the expression that has been passed to the parameter named in the attribute**.
114
How must these **parameters with special attributes be defined**?
They **must be optional by assigning default values to them**.
115
Why is it **important to find bugs early in the development** process?
The earlier a bug is discovered, the **less expensive it will be to fix**.
116
What is **unit testing**?
Unit testing **tests a small unit of code**, typically a *method* or *function*, in isolation from its dependencies.
117
What is **Test-Driven Development (TDD)**?
TDD is a principle where programmers **create unit tests before writing the code**.
118
What are the **3 unit testing frameworks** mentioned?
* **MSTest** * **NUnit** * **xUnit.net**
119
What are **integration tests**?
Integration tests **check if smaller units and larger components work together as a single piece of software**, sometimes involving *external components.*
120
What do **system tests** evaluate?
System tests **evaluate the whole system environment in which the software will run.**
121
What is **performance testing**?
Performance testing **measures how well the software performs, such as the response time for returning a web page full of data.**
122
What is **load testing**?
Load testing **measures how many requests the software can handle simultaneously while maintaining required performance**.
123
What is **user acceptance testing**?
User acceptance testing **evaluates if users can happily complete their work using the software.**
124
What should each **unit test include**?
Each unit should have **multiple tests:** **typical inputs** and **expected outputs**, **extreme input value**s to test boundaries, and **deliberately wrong inputs** to test exception handling.
125
How do you **create a new class library project** named *CalculatorLib* using Visual Studio Code?
* In **TERMINAL**, switch to the **root folder.** * Use the **dotnet CLI** to create the project: `dotnet new classlib -o CalculatorLib.` * Add the project folder to the **solution**: `dotnet sln add CalculatorLib.`
126
How do you **compile the *CalculatorLib* project** in Visual Studio Code?
In a **TERMINAL** window for the ***CalculatorLib* folder**, enter the **command**: `dotnet build`
127
How do you **create a new xUnit Test Project** named *CalculatorLibUnitTests* using Visual Studio Code?
In the **root folder**, enter the following **commands**: ``` dotnet new xunit -o CalculatorLibUnitTests dotnet sln add CalculatorLibUnitTests ```
128
How do you **add a project reference** to the *CalculatorLib* project in *CalculatorLibUnitTests* using Visual Studio Code?
Use the dotnet CLI **command**: `dotnet add reference ..\CalculatorLib\CalculatorLib.csproj`
129
Provide the **XML configuration to add a project reference** to *CalculatorLib* in *CalculatorLibUnitTests.csproj*.
``` ```
130
What are the **3 parts of a well-written unit test**?
1. **Arrange**: Declare and instantiate *variables* for input and output. 1. **Act**: *Execute* the unit being tested. 1. **Assert**: Make *assertions* about the output to verify the expected results.
131
What is the **purpose of the *Arrange* part** in a unit test?
**To set up the *inputs* and the unit under test by declaring and instantiating necessary *variables*.**
132
What is the **purpose of the *Act* part** in a unit test?
**To *execute* the function or method that you want to test.**
133
What is the **purpose of the *Assert* part** in a unit test?
**To compare the *actual results* with the *expected results* and verify the correctness of the code.**
134
Provide an **example of a unit test method for adding 2 and 2 using *xUnit***.
``` [Fact] public void TestAdding2And2() { // Arrange double a = 2; double b = 2; double expected = 4; Calculator calc = new(); // Act double actual = calc.Add(a, b); // Assert Assert.Equal(expected, actual); } ```
135
How do you **run unit tests** in Visual Studio Code?
1. Navigate to **View | Testing.** 1. In the **TESTING** window, **expand** the *CalculatorLibUnitTests* **project**. 1. **Hover over** *CalculatorUnitTests* and **click the *Run Tests*** button (black triangle icon). 1. **Check the TEST RESULTS** tab for the test results.
136
What should you do if a **unit test fails**?
**Fix the bug** in the code, then **run the unit tests *again*** to ensure all tests pass.
137
**When** should you **catch and handle an exception** in your code?
You should only catch and handle an exception **if you have enough information to mitigate the issue**. Otherwise, allow the exception to pass up through the *call stack* to a higher level.
138
What are **usage errors** in the context of **exceptions**?
Usage errors occur when a **programmer misuses a function**, typically by **passing invalid values as parameters**. These errors should be **fixed before *production runtime*.**
139
What are **execution errors**, and how do they **differ from usage errors**?
Execution errors **occur at runtime and cannot be fixed by writing "better" code.** They include **program errors**, which can be **fixed programmatically**, and **system errors**, which often **cannot be fixed *programmatically*.**
140
What should you do if a **parameter to a function should *not* be null**?
**Throw an *ArgumentNullException*.**
141
What **exception** should you throw **if a parameter value is invalid for other reasons**?
**Throw an *ArgumentException*, *NotSupportedException*, or *InvalidOperationException*.**
142
What is a **good practice** if a **function cannot successfully perform its operation**?
Consider it a **function failure** and report it by throwing an **exception**.
143
What are the **2 types of errors that *execution errors* can be split into**?
1. **Program errors** 2. **System errors**
144
What should you do if you **attempt to access a network resource but the network is down**?
Handle the system error by **logging an exception** and possibly **backing off** for a time and **trying again**.
145
Why is it **important to include a descriptive message** when throwing an **exception**?
To **help** whoever will read it (typically a *developer* or *end user*) **understand the problem.**
146
What are **guard clauses** in the context of exceptions?
Guard clauses are **static methods on exception types used to validate parameters and throw exceptions** if the values are invalid.
147
What is the **purpose of using guard clauses** in functions?
To **simplify the code** by replacing *if* statements that throw new exceptions with **static methods** that perform the same validation and exception throwing.
148
Provide an **example of using guard clauses** for parameter validation in a function.
``` static void Withdraw(string accountName, decimal amount) { ArgumentException.ThrowIfNullOrWhiteSpace(accountName, paramName: nameof(accountName)); ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount, paramName: nameof(amount)); // process parameters } ```
149
What are some **common guard clause methods** for *ArgumentException* and *ArgumentNullException*?
* ***ArgumentException***: *ThrowIfNullOrEmpty*, *ThrowIfNullOrWhiteSpace* * ***ArgumentNullException***: *ThrowIfNull*
150
List some **common guard clause methods** for *ArgumentOutOfRangeException*.
* *ThrowIfEqual*, * *ThrowIfGreaterThan*, * *ThrowIfGreaterThanOrEqual*, * *ThrowIfLessThan*, * *ThrowIfLessThanOrEqual*, * *ThrowIfNegative*, * *ThrowIfNegativeOrZero*, * *ThrowIfNotEqual*, * *ThrowIfZero*
151
What is the **entry point for a .NET console application**?
The entry point is the **Main method** in the **Program class**, or `
$` if it was created by the *top-level program* feature.
152
Explain the **structure of a call stack** in a .NET application.
The call stack is a **sequence of method calls** starting from the **entry point (*Main* method)** and **includes all the methods** that were called in sequence up to the current point of execution.
153
What should you do if an **exception is thrown in a function that does not have enough information to handle it**?
**Allow the exception to pass up through the *call stack* to a higher level** where it can be appropriately handled.
154
What happens if an **exception is not caught by any function in the call stack**?
The **exception is automatically passed up the *call stack* until it reaches the top**, where .NET outputs the *exception details.*
155
Why is it a **good practice to run code without the debugger** attached unless needed for stepping through code?
Running without the debugger attached **ensures that exceptions are output as they would be in a *production* environment**, allowing you to see how they are handled.
156
**Where** can programmers choose to **catch an exception** in their code?
Programmers can **catch an exception near the *failure point* or higher up the *call stack*** to simplify and standardize the code.
157
What is the **purpose of rethrowing an exception**?
To **catch an exception**, **log it**, and then **rethrow it** so that *higher-level code*, which may have more information, can handle it appropriately.
158
What are the **3 ways to rethrow an exception** inside a catch block?
* Using ***throw;***: Rethrows the current exception, preserving the original stack trace. For example: ```catch (Exception ex) { // Some handling code throw; }``` * Using ***throw ex;***: Rethrows the exception but resets the stack trace. For example: ```catch (Exception ex) { // Some handling code throw ex; }``` * Using ***throw new Exception("message", ex);***: Wraps the original exception inside a new exception, preserving the original exception as the InnerException. For example: ```catch (Exception ex) { // Some handling code throw new Exception("An error occurred", ex); }```
159
Why is **calling *throw ex*** usually considered **poor practice**?
Because it **loses some potentially useful information for debugging**, specifically the ***original call stack.***
160
Provide an **example of rethrowing an exception using all 3 techniques**.
``` try { Gamma(); } catch (IOException ex) { LogException(ex); // Throw the caught exception as if it happened here // this will lose the original call stack. throw ex; // Rethrow the caught exception and retain its original call stack. throw; // Throw a new exception with the caught exception nested within it. throw new InvalidOperationException( message: "Calculation had invalid values. See inner exception for why.", innerException: ex); } ```
161
What happens to the **call stack** details when you **replace *throw ex* with *throw*** in an exception handling block?
The **output includes all the details of the call stack**, retaining the *original call stack information*.
162
What is the **tester-doer pattern**?
The tester-doer pattern **uses pairs of functions: one to *perform a test* and the other to *perform an action that would fail if the test was not passed.***
163
Why might the **tester-doer** pattern add **performance overhead**?
Because it **involves performing an additional test** before executing an action, which can be *inefficient* if done repeatedly.
164
What **problem** can occur with the **tester-doer** pattern in a **multi-threaded scenario**?
A **race condition** can occur when **one thread tests** and **another thread changes the state** before the original thread proceeds, leading to *incorrect* assumptions about the state.
165
What is the **try pattern**?
The try pattern **combines the test and action parts into a single function**, such as *TryParse*, to **avoid the overhead** and potential issues of the tester-doer pattern.
166
What should you remember to do if your **try pattern function fails**?
**Set the *out* parameter to the *default* value of its type and then return *false*.**
167
Why should the ***try* pattern be preferred over the *tester-doer* pattern**?
The **try pattern avoids the *performance overhead* and potential *race conditions*** associated with the tester-doer pattern.
168
# Exercise 4.1 – Test your knowledge **What does the C# keyword *void* mean?**
The void keyword in C# **indicates that a method does not return a value**. It is used when defining a **method that *performs an action* but does not return any data**.
169
# Exercise 4.1 – Test your knowledge **What are some differences between *imperative* and *functional* programming styles?**
**Imperative Programming:** * Focuses on how to perform tasks (step-by-step instructions). * Uses statements that change a program's state. * Commonly uses loops, conditionals, and variable assignments. * Examples: C#, Java, Python (in imperative style). **Functional Programming:** * Focuses on what to perform (expressions and declarations). * Emphasizes immutability and pure functions (no side effects). * Uses functions as first-class citizens and relies heavily on recursion. * Examples: F#, Haskell, Scala, Lisp.
170
# Exercise 4.1 – Test your knowledge **In Visual Studio Code or Visual Studio, what is the difference between pressing *F5*, *Ctrl or Cmd + F5*, *Shift + F5*, and *Ctrl or Cmd + Shift + F5*?**
* **F5**: *Starts* debugging the application (Run with Debugging). If debugging is already active, it resumes execution. * **Ctrl (Cmd) + F5**: *Starts* the application *without debugging* (Run Without Debugging). * **Shift + F5**: *Stops* the current debugging session. * **Ctrl (Cmd) + Shift + F5**: *Restarts* the debugging session.
171
# Exercise 4.1 – Test your knowledge **Where does the *Trace.WriteLine* method write its output to?**
The *Trace.WriteLine* method **writes its output to trace listeners**, which by default include the **Output window** in Visual Studio and any other **listeners configured** in the application's *configuration file*.
172
# Exercise 4.1 – Test your knowledge **What are the 5 trace levels?**
1. **Off:** Turns off tracing. 1. **Error**: Logs error messages. 1. **Warning:** Logs warning messages. 1. **Info:** Logs informational messages. 1. **Verbose:** Logs all messages, including detailed tracing information.
173
# Exercise 4.1 – Test your knowledge **What is the difference between the *Debug* and *Trace* classes?**
**Debug Class:** * Used for *debugging* purposes. * Writes *output only* in debug builds. * Typically used with the *#if DEBUG* directive. * Statements are *removed in release* builds. * Example: `Debug.WriteLine("Debug info");` **Trace Class:** * Used for *both debugging and production* diagnostics. * Writes *output in both debug and release* builds. * *Not removed in release* builds. * Example: `Trace.WriteLine("Trace info");`
174
# Exercise 4.1 – Test your knowledge **When writing a unit test, what are the 3 “A”s?**
1. **Arrange**: *Set up* the objects and prepare the prerequisites for the test. 1. **Act**: *Execute* the method or functionality being tested. 1. **Assert**: *Verify* that the outcome is as expected.
175
# Exercise 4.1 – Test your knowledge **When writing a unit test using *xUnit*, which attribute must you decorate the test methods with?**
You must **decorate the test methods** with the ***[Fact]* attribute** in *xUnit*.
176
# Exercise 4.1 – Test your knowledge **What dotnet command executes *xUnit* tests?**
The `dotnet test` command executes xUnit tests.
177
# Exercise 4.1 – Test your knowledge **What statement should you use to rethrow a caught exception named *ex* without losing the stack trace?**
You should use the ***throw***; statement to rethrow a caught exception *without losing the stack trace*.