Unit 2: C# Programming Fundamentals

INT402 — Modern Web Programming Tools And Techniques 10 min read

I. Orientation — The C# Programming Model

C# is a statically typed, object-oriented programming language introduced by Microsoft with the .NET platform (2000). C# source code is compiled into Common Intermediate Language (CIL), which the Common Language Runtime (CLR) executes and manages.

  • Static typing: Every variable has a known type, such as int, string, or bool, checked mainly at compile time.
  • Managed execution: The CLR provides garbage collection, exception handling, type safety, and other runtime services.
  • Case sensitivity: total, Total, and TOTAL are different identifiers.
  • Program organization: Applications are organized into namespaces, classes, methods, statements, and expressions.
  • Object orientation: Classes combine data with operations and support encapsulation, abstraction, inheritance, and polymorphism.
  • Syntax conventions: Statements normally end with ;, while braces { } delimit blocks.
  • Entry point: A console application begins execution in a Main method or through equivalent top-level statements.

II. Language Foundations — Values, Expressions, and Basic Programs

A. Variables and Data Types

A variable is a named storage location whose declared type determines the values and operations it supports.

  • Declaration and initialization: int age = 20; declares age and assigns the integer 20.
  • Value types: Types such as int, double, char, bool, and struct store their values directly.
    • int: 32-bit signed whole number.
    • double: 64-bit floating-point number.
    • char: One UTF-16 code unit, written as 'A'.
    • bool: Either true or false.
  • Reference types: Types such as string, arrays, classes, and interfaces store references to objects.
  • Type inference: var count = 5; remains statically typed as int; var does not mean dynamically typed.
  • Constants and nullability: const double Pi = 3.14159; cannot be reassigned, while int? score = null; permits an absent value.
  • Conversion: Widening conversions may be implicit, but narrowing conversions require a cast, as in int n = (int)3.8;, producing 3.

B. C# Hello World Program

A Hello World program demonstrates the minimum structure needed to produce console output.

CSHARP
using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Hello, World!");
    }
}
  • using System: Makes names from the System namespace available without qualification.
  • Program class: Provides the class containing the application entry point.
  • static void Main(): Declares a method callable without creating a Program object; void means it returns no value.
  • Console.WriteLine: Writes the supplied string and then moves to a new output line.

C. Operators and Operator Precedence

Operators create expressions by performing arithmetic, comparison, logical, assignment, or other operations on operands.

  • Arithmetic operators: +, -, *, /, and %; integer expression 7 / 2 evaluates to 3, while 7.0 / 2 evaluates to 3.5.
  • Comparison operators: ==, !=, <, >, <=, and >= produce Boolean results.
  • Logical operators: &&, ||, and ! combine or negate Boolean expressions; && and || use short-circuit evaluation.
  • Assignment operators: =, +=, -=, *=, and /= modify variables; x += 2 means x = x + 2.
  • Precedence: Parentheses are evaluated first, followed broadly by unary, multiplicative, additive, relational, equality, logical, and assignment operators.
  • Concrete expression: 2 + 3 * 4 is 14, but (2 + 3) * 4 is 20; parentheses should clarify intended grouping.

III. Control Flow — Selection, Repetition, and Transfer

A. Conditional Statements

Conditional statements select a block of code according to a Boolean condition or matching value.

  • if statement: Executes its block only when its condition is true.
  • if-else chain: Tests alternatives in order; the first matching branch runs.
  • switch statement: Selects a case using a value or pattern and is useful for distinct alternatives.
CSHARP
if (score >= 50)
    Console.WriteLine("Pass");
else
    Console.WriteLine("Fail");
  • Condition requirement: C# requires a bool; an integer such as if (1) is invalid.
  • Scope: Variables declared inside a branch normally exist only within that block.

B. Loops: For, While and Do-While

Loops repeatedly execute statements while a repetition condition remains satisfied.

  1. for loop: Best when initialization, condition, and update form a clear counter-controlled cycle.
  2. while loop: Tests before execution, so its body may run zero times.
  3. do-while loop: Tests after execution, so its body runs at least once.
CSHARP
for (int i = 0; i < 3; i++)
    Console.WriteLine(i);
  • Iteration trace: The example prints 0, 1, and 2; i < 3 prevents a fourth iteration.
  • Termination: A loop must eventually make its condition false unless intentional infinite repetition is required.

C. Jump Statements: Break, Continue, Return and Goto

Jump statements transfer control away from the normal sequential path.

  • break: Exits the nearest loop or switch; in a search loop, it can stop after finding the target.
  • continue: Skips the remainder of the current loop iteration and proceeds to the next condition check.
  • return: Ends the current method and optionally supplies its result, as in return total;.
  • goto: Transfers control to a label or another switch case, for example goto case 0;.
  • Design constraint: Frequent goto use can obscure control flow; loops, methods, and conditionals usually express intent more clearly.

IV. Collections and Text — Storing and Transforming Sequences

A. Arrays and Types of Arrays

An array is a fixed-length, zero-indexed collection whose elements all have the same type.

  • Single-dimensional array: int[] scores = { 72, 81, 90 }; stores a linear sequence.
  • Rectangular array: int[,] grid = new int[2, 3]; represents two rows and three columns.
  • Jagged array: int[][] rows = new int[2][]; stores arrays whose lengths may differ.
  • Indexing: scores[0] accesses 72; valid indices extend from 0 to scores.Length - 1.
  • Runtime checking: An invalid index causes IndexOutOfRangeException.

B. Manipulating Arrays

Array manipulation includes traversal, element replacement, searching, sorting, copying, and resizing through replacement.

  • Traversal: foreach (int score in scores) reads each element, while for provides the index needed for modification.
  • Updating: scores[1] = 85; replaces the second element.
  • Sorting and reversing: Array.Sort(scores) sorts in place; Array.Reverse(scores) reverses the current order.
  • Searching: Array.IndexOf(scores, 90) returns the matching index or -1.
  • Copying: Array.Copy(source, target, count) copies a specified number of elements.
  • Fixed length: Arrays cannot grow in place; variable-size collections commonly use List<T>.

C. Strings and String Methods

A string is an immutable sequence of UTF-16 code units used to represent text.

  • Creation: string language = "C#"; creates a string literal.
  • Properties and methods: Length, Contains, StartsWith, EndsWith, IndexOf, Substring, Replace, ToUpper, ToLower, and Trim inspect or derive text.
  • Comparison: string.Equals(a, b, StringComparison.OrdinalIgnoreCase) performs explicit case-insensitive ordinal comparison.
  • Immutability: A method such as language.Replace("#", "Sharp") returns a new string; it does not alter language.
  • Empty values: string.IsNullOrWhiteSpace(value) detects null, empty, or whitespace-only text.

D. Manipulating Strings

String manipulation constructs, divides, joins, formats, or parses textual data.

  • Concatenation: "Hello, " + name combines strings, while $"Hello, {name}" uses interpolation.
  • Splitting and joining: "red,green".Split(',') creates parts; string.Join("-", parts) combines them.
  • Efficient repeated changes: StringBuilder avoids creating many intermediate strings during intensive concatenation.
  • Parsing: int.TryParse(text, out int number) reports success without throwing for invalid numeric input.
  • Concrete transformation: " CSharp ".Trim().ToUpper() produces "CSHARP" as a new string.

V. Object-Oriented Design — Types, Reuse, and Dynamic Behavior

A. Object-Oriented Programming Concepts

Object-oriented programming models a system as interacting objects that hold state and expose behavior.

  • Identity: Two objects can contain equal data but remain separate instances.
  • State: Fields and properties represent data, such as an account balance.
  • Behavior: Methods represent operations, such as Deposit.
  • Core principles: Encapsulation protects state, abstraction exposes essentials, inheritance enables specialization, and polymorphism supports substitutable behavior.

B. Classes and Objects

A class defines a reference type, while an object is a runtime instance of that class.

CSHARP
class Counter
{
    public int Value { get; private set; }
    public void Increment() => Value++;
}

Counter counter = new Counter();
counter.Increment();
  • Members: Classes can contain fields, properties, methods, constructors, events, and nested types.
  • Instantiation: new Counter() allocates and initializes an object.
  • Access: The object reference counter accesses public members through the dot operator.

C. Encapsulation and Abstraction

Encapsulation controls access to implementation details, while abstraction presents a focused public model.

  1. Encapsulation: Access modifiers such as private, protected, internal, and public define member visibility; private set prevents external property assignment.
  2. Abstraction: Public methods express what an object does without exposing every internal step; account.Withdraw(50) hides balance-validation logic.
    • Invariant protection: Validation inside a property setter or method can prevent impossible states, such as a negative age.

D. Constructors

A constructor initializes a new object and has the same name as its class with no return type.

  • Parameterized constructor: Person(string name) { Name = name; } requires initialization data.
  • Default constructor: If no instance constructor is declared, C# generally supplies a parameterless one.
  • Overloading: Multiple constructors may differ by parameter lists.
  • Constructor chaining: Person() : this("Unknown") { } delegates to another constructor.
  • Base initialization: A derived constructor can invoke base(arguments) before initializing derived members.

E. Inheritance

Inheritance creates a derived class that reuses and specializes an accessible base-class implementation.

  • Declaration: class Manager : Employee makes Manager derive from Employee.
  • Inherited members: Public and protected members are accessible according to their modifiers; private base members are not directly accessible.
  • Substitutability: A Manager object can be assigned to an Employee variable.
  • Constraint: C# classes support one direct base class, although a class may implement multiple interfaces.
  • Purpose: Inheritance should represent a genuine “is-a” relationship, such as Manager being an Employee.

F. Polymorphism

Polymorphism allows one common type to invoke behavior whose implementation depends on the actual object.

  • Overriding: A base method marked virtual may be replaced by a derived method marked override.
  • Dynamic dispatch: Calling employee.CalculatePay() can execute Manager.CalculatePay() when the object is a Manager.
  • Method overloading: Methods sharing a name but having different parameter lists provide compile-time polymorphism.
  • Interface polymorphism: Different classes implementing the same interface can be processed through one interface reference.
  • Benefit: Client code depends on a stable contract rather than numerous concrete-type checks.

G. Abstract Classes

An abstract class is an incomplete base type intended for inheritance and cannot be instantiated directly.

  • Declaration: abstract class Shape establishes the abstract base.
  • Abstract member: public abstract double Area(); provides no body and must be implemented by a non-abstract derived class.
  • Concrete member: An abstract class may also provide fields, constructors, and implemented methods shared by subclasses.
  • Use case: Circle and Rectangle can inherit common Shape behavior while calculating area differently.
  • Interface contrast: An abstract class can maintain shared instance state, while interfaces primarily define implementable contracts.

VI. Runtime Reliability — Detecting and Recovering from Failures

A. Exception Handling

Exception handling separates normal program logic from the controlled processing of runtime failures.

  • try block: Contains operations that may throw an exception.
  • catch block: Handles a compatible exception type, such as FormatException or IOException.
  • finally block: Executes whether an exception occurs or not, making it suitable for essential cleanup.
  • throw statement: Raises an exception, as in throw new ArgumentException("Invalid age");; throw; preserves the current exception’s stack trace when rethrowing.
  • Specific handling: Catch specific exceptions before general ones because catch blocks are checked from top to bottom.
  • Resource management: A using statement or declaration reliably disposes resources and is generally preferable to manual cleanup.
  • Design rule: Exceptions represent exceptional failures, not routine branching; expected invalid input can often be handled with methods such as TryParse.