Unit 2: C# Programming Fundamentals

CSE253 — .Net Programming 9 min read

I. Orientation

C# is a strongly typed, object-oriented language developed by Microsoft for the .NET platform. A C# program is compiled into Intermediate Language (IL), executed by the Common Language Runtime (CLR), and organized into namespaces, classes, methods, and statements.

  • Strong typing: Every variable has a defined type, such as int, double, char, or string.
  • Managed execution: The CLR provides memory management, exception handling, and runtime services.
  • Object orientation: Programs are designed using classes, objects, inheritance, encapsulation, abstraction, and polymorphism.
  • Statement conventions: Most statements end with ;, code blocks use { }, and identifiers are case-sensitive.
  • Type safety: The compiler detects many invalid assignments and operations before execution.
  • Entry point: Console applications commonly begin execution in a Main method.

II. Variables, Types, and Console Programs

This section introduces the data stored by a program and the basic mechanism for communicating with users.

A. Variables and Data Types

A variable is a named memory location whose type determines the values it can store and the operations it supports.

  • Declaration: int age; declares an integer variable named age.
  • Initialization: double price = 49.95; assigns an initial value during declaration.
  • Value types: int, double, bool, char, and struct store their data directly.
    • int commonly stores whole numbers from approximately −2.1 billion to 2.1 billion.
    • bool stores only true or false.
  • Reference types: string, arrays, classes, and objects store references to data managed on the heap.
  • Constants: const double Pi = 3.14159; prevents reassignment after declaration.
  • Type conversion: int.Parse("25") converts text to an integer; Convert.ToDouble("4.5") converts text to a double.
  • Nullable values: int? score = null; permits an integer to have no value.

B. Input and Output Operations

Console input and output allow a program to receive text and display results through standard streams.

  • Output: Console.WriteLine("Hello"); prints text followed by a new line.
  • Formatted output: $"Total: {total:C}" inserts the value of total using currency formatting.
  • Input: string name = Console.ReadLine(); reads one line as a string.
  • Numeric input: int number = int.Parse(Console.ReadLine()); converts user text to an integer.
  • Safe conversion: int.TryParse(text, out int value) returns false instead of throwing an exception for invalid input.
  • Character output: Console.Write('A'); writes a single char, whereas Console.Write("A") writes a string.

C. C# Hello World Program

The Hello World program demonstrates the minimum structure of a console application.

CSHARP
using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Hello, World!");
    }
}
  • Namespace import: using System; makes Console available without writing System.Console.
  • Class: Program contains the application code.
  • Entry point: static void Main() is where execution begins.
  • Output statement: Console.WriteLine displays the literal string and terminates the line.
  • Compilation: The compiler checks syntax and types before the CLR executes the resulting assembly.

III. Control Flow

Control-flow statements determine which statements execute and how many times they execute.

A. Conditional Statements

Conditional statements select actions according to Boolean expressions.

  • if: Executes a block when a condition is true.
    CSHARP
      if (marks >= 50)
          Console.WriteLine("Pass");
  • else: Executes an alternative block when the if condition is false.
  • else if: Tests multiple mutually exclusive conditions, such as grade boundaries.
  • switch: Compares one expression with several case labels.
    CSHARP
      switch (day)
      {
          case 1: Console.WriteLine("Monday"); break;
          default: Console.WriteLine("Other"); break;
      }
  • Conditional operator: string result = age >= 18 ? "Adult" : "Minor"; is a compact two-way choice.
  • Boolean operators: && means AND, || means OR, and ! negates a condition.

B. Loops

Loops repeat a block while a controlling condition or collection requires execution.

  • for: Best for a known counter range, such as indexes 0 through length - 1.
    CSHARP
      for (int i = 0; i < 3; i++)
          Console.WriteLine(i);
  • while: Tests its condition before each iteration and may execute zero times.
  • do-while: Executes once before testing its condition, making it useful for menu input.
  • foreach: Visits every element in an array or collection without manually managing an index.
  • Loop control: The condition must eventually become false; otherwise, the program enters an infinite loop.
  • Performance: Repeated work should be kept inside the loop only when necessary, especially for large collections.

C. Jump Statements

Jump statements alter normal sequential or repetitive execution.

  • break: Immediately exits the nearest loop or switch; in a search loop, it stops after finding the required item.
  • continue: Skips the remaining statements in the current iteration and begins the next iteration.
  • return: Exits a method and can provide a value, such as return sum;.
  • goto: Transfers control to a label but is generally avoided because it can make program flow difficult to follow.
  • throw: Transfers control to exception handling by raising an exception object.

IV. Arrays and Text

Arrays store ordered values of one type, while strings provide specialized operations for character sequences.

A. Arrays

An array is a fixed-size, zero-indexed collection whose elements share one data type.

  • Declaration and creation: int[] scores = new int[3]; creates indexes 0, 1, and 2.
  • Initialization: int[] values = { 10, 20, 30 }; creates an array with three elements.
  • Access: scores[0] refers to the first element; scores.Length gives the number of elements.
  • Traversal: foreach (int score in scores) reads each value in order.
  • Multidimensional arrays: int[,] matrix = new int[2, 3]; represents two rows and three columns.
  • Bounds: Accessing an index outside the valid range causes IndexOutOfRangeException.
  • Array methods: Array.Sort(values) orders elements, while Array.Reverse(values) reverses their order.

B. Strings and String Methods

A string is an immutable sequence of Unicode characters, so operations produce a new string rather than changing the original.

  • Creation: string text = "CSharp"; stores six characters.
  • Length and indexing: text.Length returns 6, and text[0] returns 'C'.
  • Searching: Contains("Sharp") checks presence; IndexOf("a") returns the first matching position.
  • Extraction: Substring(1, 3) extracts three characters beginning at index 1.
  • Transformation: ToUpper(), ToLower(), and Trim() return transformed strings.
  • Splitting and joining: "A,B,C".Split(',') creates an array; string.Join("-", parts) combines values.
  • Comparison: Equals or StringComparison.OrdinalIgnoreCase provides controlled comparison behavior.
  • Formatting: Interpolation, such as $"Name: {name}", is clearer than repeated concatenation.

V. Collections

Collections provide flexible alternatives to fixed-size arrays and are usually found in System.Collections.Generic.

A. Collections in C

Collections manage groups of objects with different access and lookup requirements.

  • List<T>: A dynamically sized, ordered collection; List<int> numbers = new(); supports Add and Remove.
  • Dictionary<TKey,TValue>: Stores key-value pairs; ages["Mina"] = 21 associates a name with an age.
  • Queue<T>: Follows FIFO, or first-in-first-out, order through Enqueue and Dequeue.
  • Stack<T>: Follows LIFO, or last-in-first-out, order through Push and Pop.
  • Generics: List<string> restricts elements to strings and reduces casting errors.
  • Enumeration: foreach works with collections implementing IEnumerable.
  • Selection principle: Choose List<T> for indexed sequences and Dictionary for fast lookup by a unique key.

VI. Methods and Object Construction

Methods organize behavior, and classes provide the templates from which objects are created.

A. Methods and Parameter Passing

A method is a named block of code that may accept parameters and return a value.

  • Signature: static int Add(int a, int b) includes the name, parameter types, and return type.
  • Return value: return a + b; sends an integer result to the caller.
  • void: A void method performs an action without returning a value.
  • Value parameters: void Change(int x) receives a copy, so changing x does not change the caller’s variable.
  • Reference parameters: ref allows a method to modify an existing variable, and the caller must initialize it first.
  • Output parameters: out allows a method to assign a result, as in int.TryParse.
  • params: params int[] values accepts a variable number of integer arguments.
  • Overloading: Multiple methods may share a name if their parameter lists differ.

B. Classes and Objects

A class is a blueprint containing fields, properties, methods, and constructors; an object is an instance of that class.

  • Class definition: class Student { public string Name; } declares a reference type.
  • Object creation: Student s = new Student(); allocates an object and assigns its reference to s.
  • Members: Properties expose controlled data, while methods represent behavior.
  • Instance access: The dot operator, s.Name, accesses a member through an object.
  • Static members: Belong to the class itself and can be accessed without creating an object.
  • Object identity: Two objects may contain equal data but remain separate instances in memory.

C. Constructors

A constructor initializes an object when the new operator creates it.

  • Naming rule: A constructor has the same name as its class and no return type.
  • Default constructor: If no constructor is declared, C# may provide a parameterless constructor.
  • Parameterized constructor:
    CSHARP
      public Student(string name)
      {
          Name = name;
      }
  • Constructor overloading: A class can provide both parameterless and parameterized initialization.
  • this: this.Name = name; distinguishes the instance property from the parameter.
  • Initialization purpose: Constructors establish valid starting state, such as requiring a nonempty student name.

D. Access Modifiers

Access modifiers control where types and members can be used.

  • public: Accessible from any code that can access the containing type.
  • private: Accessible only inside the declaring class; this is the default for class fields.
  • protected: Accessible inside the class and its derived classes.
  • internal: Accessible within the same assembly.
  • protected internal: Accessible from the same assembly or from derived classes.
  • Design rule: Keep fields private and expose only the operations or properties that callers require.

VII. Object-Oriented Programming Concepts

Object-oriented programming models a system as cooperating objects that combine state and behavior.

A. Object-Oriented Programming Concepts - Encapsulation

Encapsulation bundles data with its methods and restricts direct access to internal state.

  • Private state: private decimal balance; prevents outside code from assigning arbitrary values.
  • Controlled access: A Deposit(decimal amount) method can reject values where amount <= 0.
  • Property validation: A setter can enforce rules before storing a value.
  • Benefit: Invariants remain inside the class rather than being duplicated across callers.

B. Object-Oriented Programming Concepts - Abstraction

Abstraction exposes essential behavior while hiding implementation details.

  • Abstract class: May define shared code and abstract methods that derived classes must implement.
  • Interface: interface IPrintable { void Print(); } specifies a contract without requiring one implementation.
  • Usage: Calling printer.Print() focuses on the operation, not how printing is performed.
  • Benefit: Implementations can change without changing dependent code.

C. Object-Oriented Programming Concepts - Inheritance

Inheritance creates a derived class that reuses or specializes members of a base class.

  • Syntax: class Dog : Animal makes Dog derive from Animal.
  • Reuse: Public and protected base members are available according to their accessibility.
  • Specialization: Dog may add Bark() while retaining common animal behavior.
  • Design caution: Inheritance should represent a genuine “is-a” relationship; composition is often better for “has-a” relationships.

D. Object-Oriented Programming Concepts - Polymorphism

Polymorphism allows one interface or base reference to represent objects with different implementations.

  • Virtual dispatch: A base method marked virtual can be replaced with override in a derived class.
  • Example: An Animal reference can call Speak() on either a Dog or Cat, using the actual object’s override.
  • Compile-time form: Method overloading selects among signatures during compilation.
  • Run-time form: Method overriding selects behavior during execution.

VIII. Reliability and Maintenance

Reliable programs anticipate failures, manage external resources, and use systematic diagnosis.

A. Exception Handling

Exception handling separates normal logic from responses to run-time errors.

  • try: Contains statements that may fail, such as file access or numeric conversion.
  • catch: Handles a matching exception type, for example FormatException.
  • finally: Runs whether an exception occurs or not, making it suitable for cleanup.
  • throw: Raises an exception when a method detects an invalid state.
  • Specificity: Catch specific exceptions before general Exception to preserve useful error information.
  • Example: Parsing "abc" as an integer raises FormatException; TryParse can avoid that exception for expected invalid input.

B. File Handling and Debugging Fundamentals

File handling reads and writes persistent data, while debugging locates and corrects incorrect behavior.

  • Writing: File.WriteAllText("log.txt", content) creates or replaces a text file.
  • Reading: File.ReadAllLines("log.txt") returns the file’s lines as a string array.
  • Appending: File.AppendAllText adds content without replacing existing text.
  • Resource safety: using or using declarations ensure streams are disposed after use.
  • Path errors: Invalid paths, missing files, and denied permissions commonly produce IOException or related exceptions.
  • Breakpoints: Pause execution at a selected line so variable values and control flow can be inspected.
  • Stepping: Step over, into, or out of methods to isolate the statement producing incorrect behavior.
  • Diagnostic tools: Use meaningful variable names, logging, debugger watches, and exception stack traces to identify the failing operation and call path.