(5)From Nurse to C# Developer -- C# Advanced Basics: Exception Handling and Program Control

(5)From Nurse to C# Developer -- C# Advanced Basics: Exception Handling and Program Control

On the fifth day of learning C# programming, I studied exception handling, variable scope, switch-case statements, and loop structures. As a nurse turned developer, I try to combine these programming concepts with nursing work experience.

Last updated 3/6/2025 8:43 PM
勇敢的天使
18 min read
Category
Sharing Course
Topic
From Nurse to C# Developer
Tags
.NET C# Career Change to Development Programming Loop Structures

In the previous lesson, I learned about type conversion, arithmetic operators, relational operators, logical operators, and various branching structures, understanding the meaning and execution process of these syntaxes. Today's course focuses on how to make our programs more robust and reduce the likelihood of errors. I learned another branching structure switch-case and compared it with the branching structures learned in the previous lesson. Additionally, I learned about loop structures, which are a more important and complex part of what has been covered so far. To better absorb and understand this knowledge, I slowed down my learning pace and reinforced my understanding through continuous coding. Below are the specific contents I learned in this lesson:

I. Exception Handling

In nursing work, we often need to deal with various unexpected situations. For example, a thermometer may malfunction when measuring a patient's temperature, or an IV line may become blocked during infusion. Similarly, in programming, we need to handle various exceptional situations. C# provides an exception handling mechanism to help us handle these issues gracefully.

1. Basic syntax of try-catch

try
{
    // Code that may cause an exception
}
catch (Exception ex)
{
    // Code to handle the exception
}

2. Practical application example

The following is an example of recording patient vital signs data in nursing work:

try
{
    Console.Write("Please enter patient temperature: ");
    double temperature = Convert.ToDouble(Console.ReadLine());

    if (temperature < 35 || temperature > 42)
    {
        throw new Exception("Temperature data abnormal, please recheck");
    }

    Console.Write("Please enter systolic pressure: ");
    int systolicPressure = Convert.ToInt32(Console.ReadLine());

    if (systolicPressure < 60 || systolicPressure > 200)
    {
        throw new Exception("Blood pressure data abnormal, please remeasure");
    }

    Console.WriteLine($"Recorded temperature: {temperature}°C");
    Console.WriteLine($"Recorded systolic pressure: {systolicPressure}mmHg");
}
catch (FormatException)
{
    Console.WriteLine("Input format error, please enter a valid number");
}
catch (OverflowException)
{
    Console.WriteLine("The input value is out of range");
}
catch (Exception ex)
{
    Console.WriteLine($"Error occurred: {ex.Message}");
    // Error log can be recorded here
}
finally
{
    Console.WriteLine("Data entry operation completed");
    // Cleanup work that will execute regardless of exception occurrence
}

3. Common exception types

In nursing information systems, we often encounter the following exceptions:

  • FormatException: Thrown when the input data format is incorrect, such as entering letters instead of numbers
  • OverflowException: Thrown when the value exceeds the range of the type
  • ArgumentException: Thrown when the parameter value does not meet requirements
  • NullReferenceException: Thrown when attempting to access a null object

4. Custom exceptions

Sometimes we need to throw custom exceptions based on business logic:

public class VitalSignException : Exception
{
    public VitalSignException(string message) : base(message)
    {
    }
}

try
{
    int heartRate = 150;
    if (heartRate > 120)
    {
        throw new VitalSignException("Heart rate abnormally elevated, needs immediate attention!");
    }
}
catch (VitalSignException ex)
{
    Console.WriteLine($"Vital sign abnormality: {ex.Message}");
    // Emergency handling process can be added here
}

5. Best practices

  1. Catch only expected exceptions; avoid catching all exceptions
  2. Handle exceptions at the appropriate level
  3. Record exception information for subsequent analysis
  4. Use finally blocks for cleanup work
  5. Provide meaningful error messages

II. Variable Scope

Variable scope refers to the range within which a variable can be used. Just as in a hospital, nurses in different departments can only view patient information for their own department, variables also have limitations on their usage range.

1. Local variables

The scope of a local variable starts from the opening brace where it is declared and ends at the corresponding closing brace. This is like a temporary record sheet used internally at a nurse station:

void RecordPatientVitals()
{
    // temperature is only valid within this method
    double temperature = 36.5;

    if (temperature > 37.3)
    {
        // fever is only valid within this if block
        string fever = "Fever";
        Console.WriteLine(fever);
    }
    // fever variable cannot be used here

    {
        // pulse is only valid within this code block
        int pulse = 80;
    }
    // pulse variable cannot be used here
}

2. Class-level variables (member variables)

Class-level variables are visible throughout the entire class, like a nursing record sheet for a ward that can be accessed by nurses across all shifts:

public class Patient
{
    // These variables are accessible throughout the class
    private string patientName;
    private int patientAge;
    private string bedNumber;

    public void AdmitPatient(string name, int age)
    {
        patientName = name;  // Can access class-level variable
        patientAge = age;    // Can access class-level variable
    }

    public void AssignBed(string bed)
    {
        bedNumber = bed;     // Can access class-level variable
    }
}

3. Global variables (static variables)

Static variables can be accessed throughout the entire program, similar to hospital-wide general regulations:

public class HospitalConstants
{
    // These static variables can be accessed anywhere
    public static readonly double NORMAL_TEMPERATURE = 37.0;
    public static readonly int NORMAL_SYSTOLIC_PRESSURE = 120;
    public static readonly int NORMAL_DIASTOLIC_PRESSURE = 80;
}

public class NursingRecord
{
    public void CheckTemperature(double temperature)
    {
        // Static variables of HospitalConstants can be accessed in any class
        if (temperature > HospitalConstants.NORMAL_TEMPERATURE)
        {
            Console.WriteLine("Temperature is high");
        }
    }
}

4. Variable shadowing

When a local variable has the same name as a class-level variable, the local variable "shadows" the class-level variable:

public class VitalSigns
{
    private double temperature = 36.5; // Class-level variable

    public void UpdateTemperature(double temperature) // Parameter
    {
        // Here, temperature refers to the parameter, not the class-level variable
        Console.WriteLine($"New temperature: {temperature}");

        // Use the 'this' keyword to access the class-level variable
        this.temperature = temperature;
    }
}

5. Best practices for scope

  1. The scope of a variable should be as small as possible to reduce the likelihood of errors
  2. Avoid using global variables because they can be modified by any code
  3. Use meaningful variable names that reflect their purpose
  4. Release resources that are no longer needed promptly
  5. Be aware of the variable's lifecycle and avoid accessing variables that have gone out of scope

III. switch-case Statement

In nursing work, we often need to make different handling decisions based on different situations. The switch-case statement is like a standard treatment procedure used in nursing: selecting the appropriate plan based on the situation.

1. Supported types

The switch statement supports the following types of expressions:

  • Integer types (int, long, byte, etc.)
  • Character type (char)
  • String type (string)
  • Enumeration type (enum)
  • Boolean type (bool) - C# 7.0 and above
  • Pattern matching (C# 7.0 and above)
    • Type pattern
    • Constant pattern
    • var pattern
    • Property pattern (C# 8.0 and above)

Example:

// Enum type example
enum PatientStatus
{
    Normal,
    Fever,
    Pain,
    Critical
}

PatientStatus status = PatientStatus.Fever;
switch (status)
{
    case PatientStatus.Normal:
        Console.WriteLine("Continue observation");
        break;
    case PatientStatus.Fever:
        Console.WriteLine("Perform cooling treatment");
        break;
    case PatientStatus.Pain:
        Console.WriteLine("Provide pain relief");
        break;
    case PatientStatus.Critical:
        Console.WriteLine("Notify doctor immediately");
        break;
}

// Pattern matching example (C# 7.0+)
object obj = "Nursing record";
switch (obj)
{
    case string s:
        Console.WriteLine($"This is a string: {s}");
        break;
    case int n:
        Console.WriteLine($"This is an integer: {n}");
        break;
    case null:
        Console.WriteLine("Object is null");
        break;
    default:
        Console.WriteLine("Unknown type");
        break;
}

2. Basic syntax

switch (expression)
{
    case constant1:
        statement1;
        break;
    case constant2:
        statement2;
        break;
    default:
        default statement;
        break;
}

3. Practical application example

For example, taking different nursing measures based on the patient's pain level:

int painLevel = 3; // Pain level (0-10)
switch (painLevel)
{
    case 0:
        Console.WriteLine("No pain relief needed");
        break;
    case 1:
    case 2:
    case 3:
        Console.WriteLine("Suggest non-drug treatments, such as massage, hot compress, etc.");
        break;
    case 4:
    case 5:
    case 6:
        Console.WriteLine("Consider oral painkillers");
        break;
    case 7:
    case 8:
    case 9:
    case 10:
        Console.WriteLine("Need immediate treatment, consider injectable painkillers");
        break;
    default:
        Console.WriteLine("Invalid pain level");
        break;
}

4. Important notes

  1. Importance of break statement: Each case branch must end with a break, otherwise execution will continue to the next case
  2. Case merging: Multiple cases can share the same handling logic, as shown in the pain level grouping example
  3. default branch: Used to handle all unspecified situations, similar to contingency plans in nursing

5. Comparison of branching structures

Differences between if, if-else, and switch

  1. Condition type:

    • if: Can evaluate any expression that returns a boolean value
    • if-else: Can also evaluate any boolean condition but provides an alternative
    • switch: Can only evaluate equality and requires constant expressions
  2. Applicable scenarios:

    • if: Suitable for single condition evaluation
    • if-else: Suitable for evaluating two or more conditions
    • switch: Suitable for evaluating multiple equality conditions
  3. Performance considerations:

    • When branches are few, performance is similar
    • When branches are many, switch usually performs better than multiple if-else because the compiler can optimize it into a jump table

Detailed comparison of if-else if and switch-case

// Using if-else if
if (patientStatus == "Fever")
{
    Console.WriteLine("Perform physical cooling");
    CheckTemperature();
}
else if (patientStatus == "Pain")
{
    Console.WriteLine("Assess pain level");
    PainAssessment();
}
else if (patientStatus == "Bleeding")
{
    Console.WriteLine("Stop bleeding immediately");
    StopBleeding();
}
else
{
    Console.WriteLine("Continue observation");
}

// Using switch-case
switch (patientStatus)
{
    case "Fever":
        Console.WriteLine("Perform physical cooling");
        CheckTemperature();
        break;
    case "Pain":
        Console.WriteLine("Assess pain level");
        PainAssessment();
        break;
    case "Bleeding":
        Console.WriteLine("Stop bleeding immediately");
        StopBleeding();
        break;
    default:
        Console.WriteLine("Continue observation");
        break;
}

Main differences:

  1. Syntax structure:

    • if-else if structure is more flexible and can handle complex condition evaluation
    • switch-case structure is more standardized and code is cleaner
  2. Condition restrictions:

    • if-else if can use any conditional expression
    • switch-case can only use equality comparison
  3. Execution flow:

    • if-else if evaluates conditions one by one
    • switch-case jumps directly to the matching case
  4. Code maintainability:

    • When there are many branches, switch-case usually has better readability and maintainability
    • if-else if is suitable for handling complex logic judgments
  5. Performance considerations:

    • For a large number of branches, switch-case usually performs better
    • For a small number of branches, the performance difference is insignificant

6. Usage suggestions

  1. When you need to perform different operations based on different values of a variable, prefer using switch-case
  2. When there are many branches, switch-case readability is usually better than if-else
  3. For complex condition evaluations (such as range evaluation), using if-else is more appropriate
  4. Ensure that all possible situations have corresponding handling logic

IV. Loop Structures

In nursing work, we often need to repeat certain operations, such as measuring vital signs every hour or making rounds for each patient in the ward. In programming, loop structures are used to handle such repetitive tasks.

1. while loop

A while loop repeatedly executes a block of code as long as the condition is true. This is like continuously monitoring a patient's temperature until it returns to normal:

double temperature = 39.0;
while (temperature > 37.3)
{
    Console.WriteLine($"Current temperature: {temperature}°C, cooling needed");
    // Simulate cooling treatment
    temperature -= 0.2;
    Console.WriteLine("Performing physical cooling...");
    Thread.Sleep(1000); // Simulate waiting for a period
}
Console.WriteLine("Temperature returned to normal");

2. do-while loop

A do-while loop executes the code block at least once before evaluating the condition. This is similar to having to measure a patient's temperature at least once before deciding whether continued monitoring is necessary:

int painLevel;
do
{
    Console.WriteLine("Please assess pain level (0-10):");
    painLevel = Convert.ToInt32(Console.ReadLine());

    if (painLevel > 0)
    {
        Console.WriteLine("Implementing pain relief measures...");
        // Perform pain treatment
    }
} while (painLevel > 3); // Continue monitoring when pain level is greater than 3

3. for loop

A for loop is typically used when the exact number of iterations is known. For example, when making rounds to check each bed's patient:

int bedCount = 6; // Assume the ward has 6 beds
for (int bedNumber = 1; bedNumber <= bedCount; bedNumber++)
{
    Console.WriteLine($"Checking patient in bed {bedNumber}");
    // Perform rounding operation
    CheckPatientStatus(bedNumber);
}

4. foreach loop

A foreach loop is used to iterate over each element in a collection. For example, viewing all pending nursing tasks:

List<string> nursingTasks = new List<string>
{
    "Measure vital signs",
    "Replace medication fluid",
    "Wound care",
    "Document in medical record"
};

foreach (string task in nursingTasks)
{
    Console.WriteLine($"Executing nursing task: {task}");
    // Execute nursing task
    PerformNursingTask(task);
}

5. Loop control statements

  1. break statement: Immediately exits the loop
while (true)
{
    double temperature = MeasureTemperature();
    if (temperature <= 37.3)
    {
        Console.WriteLine("Temperature normal, stop monitoring");
        break; // Exit loop when temperature is normal
    }
    // Continue monitoring
}
  1. continue statement: Skips the remaining part of the current iteration and proceeds to the next iteration
for (int bedNumber = 1; bedNumber <= 6; bedNumber++)
{
    if (IsBedEmpty(bedNumber))
    {
        continue; // Skip current iteration if the bed is empty
    }
    // Perform nursing operations for occupied beds
    ProvideNursing(bedNumber);
}

6. Best practices for loops

  1. Choose the appropriate loop type:

    • Use while when the number of iterations is unknown
    • Use do-while when at least one execution is required
    • Use for when the exact number of iterations is known
    • Use foreach when iterating over a collection
  2. Avoid infinite loops:

    • Ensure the loop condition will eventually become false
    • Use the break statement to exit the loop when appropriate
  3. Performance considerations:

    • Avoid unnecessary calculations inside the loop
    • Minimize the number of nested loops
    • Use the continue statement to skip unnecessary operations
  4. Code readability:

    • Use meaningful loop variable names
    • Add appropriate comments to explain the purpose of the loop
    • Keep the loop body concise
  5. Exception handling:

    • Include appropriate exception handling within the loop
    • Consider potential error situations that may occur during the loop

7. Application scenarios for loops

  1. Data processing:
List<Patient> patients = GetAllPatients();
foreach (Patient patient in patients)
{
    UpdatePatientRecord(patient);
}
  1. Input validation:
string input;
do
{
    Console.Write("Please enter a valid temperature value (35-42):");
    input = Console.ReadLine();
} while (!IsValidTemperature(input));
  1. Scheduled tasks:
while (isNightShift)
{
    // Check patients every two hours
    CheckPatients();
    Thread.Sleep(TimeSpan.FromHours(2));
}

Through these loop structures, we can handle repetitive nursing tasks more efficiently, improving work efficiency and accuracy. In programming, using loops appropriately makes our code cleaner and more maintainable.

V. Program Debugging

In nursing work, we often need to verify the execution of medical orders and check the accuracy of nursing records. Similarly, in programming, we need to check whether the program executes as expected. Program debugging is such a process of verification and error correction.

1. Debugging methods

  1. F11 Step Into (Single-step debugging)

    • Execute code line by line to see the execution details of each step
    • Like verifying the medical order execution process step by step
    • Suitable for locating the specific line of code where a problem occurs
  2. F10 Step Over

    • Execute code as a procedure, skipping the detailed execution inside functions
    • Similar to focusing on key items during rounds, temporarily ignoring minor details
    • Suitable for quickly understanding the overall execution flow of the program
  3. Breakpoint debugging

    • Set breakpoints at key lines of code; the program pauses when it hits a breakpoint
    • Like focusing on checking the condition of certain special patients before shift handover
    • Convenient for viewing variable values and program state at specific locations

2. Debugging example

public class PatientMonitor
{
    public void MonitorVitalSigns(Patient patient)
    {
        // Set breakpoint to check basic patient information
        var temperature = MeasureTemperature(patient);

        if (temperature > 37.3)
        {
            // Use F11 to step into the function to see the measurement process
            // Use F10 to skip the internal details of the handling function
            HandleFever(patient, temperature);
        }

        // Continue monitoring other vital signs
        CheckBloodPressure(patient);
        CheckHeartRate(patient);
    }
}

3. Debugging tips

  1. Set breakpoints reasonably

    • Set breakpoints at code locations where problems may occur
    • Set breakpoints at the starting points of critical business logic
    • Set breakpoints at exception handling code
  2. Use watch windows

    • Add key variables to the watch window
    • Observe changes in variable values in real time
    • Verify the correctness of data processing
  3. Conditional breakpoints

    • Set breakpoints that trigger only under specific conditions
    • For example, pause the program only when temperature exceeds 39 degrees

Summary

In this lesson, we learned the following important topics:

  1. Exception handling

    • Use of try-catch structure
    • Handling methods for different types of exceptions
    • Creation and use of custom exceptions
  2. Variable scope

    • Differences between local variables, class-level variables, and static variables
    • Variable shadowing phenomenon
    • Best practices for scope
  3. Branching structures

    • Basic usage of switch-case statement
    • Supported data types and pattern matching
    • Comparison and selection with if-else structures
  4. Loop structures

    • Usage scenarios of while, do-while, for, foreach
    • Loop control statements (break, continue)
    • Best practices and performance considerations for loops
  5. Program debugging

    • Step Into and Step Over debugging
    • Setting and using breakpoints
    • Effective use of debugging tools

As a learner transitioning from nursing to programming, I find many similarities between programming concepts and nursing work. Just as nursing work requires rigorous operating procedures, clear documentation, and timely exception handling, programming also needs standardized code structure, clear logic, and comprehensive error handling.

Through learning these foundational concepts, I am gradually building my programming mindset and can better understand and solve programming problems. In the following studies, I will continue to delve deeper into the features of C# programming, laying a solid foundation for becoming an excellent developer.

Keep Exploring

Related Reading

More Articles