C# Fundamentals

C# (pronounced "C Sharp") is a modern, type-safe, object-oriented programming language developed by Microsoft. It runs on the .NET platform and is widely used for building enterprise applications, web services, desktop applications, and cloud-native systems. Understanding C# fundamentals is essential for developers working in the Microsoft ecosystem and platform engineering.

What is C#

C# is a statically-typed, compiled language that combines the power of C++ with the simplicity of Visual Basic. It was designed to be simple, modern, and general-purpose, making it suitable for a wide range of development scenarios.

Key characteristics:

graph TB A[C# Source Code] --> B[C# Compiler] B --> C[Intermediate Language - IL] C --> D[CLR - Common Language Runtime] D --> E[JIT Compilation] E --> F[Native Machine Code] F --> G[Execution]

Basic Syntax and Data Types

C# provides a rich set of built-in data types divided into value types and reference types.

Value Types

Value types store data directly and are allocated on the stack.

// Integer types int age = 30; long population = 7800000000L; short temperature = -15; byte level = 255; // Floating-point types float rate = 3.14f; double price = 19.99; decimal money = 1234.56m; // Use for financial calculations // Boolean bool isActive = true; // Character char grade = 'A';

Reference Types

Reference types store a reference to the data and are allocated on the heap.

// String string name = "Alice"; string message = $"Hello, {name}!"; // String interpolation // Arrays int[] numbers = { 1, 2, 3, 4, 5 }; string[] names = new string[3]; // Objects object obj = new object();

Variables and Constants

// Variable declaration int count = 0; string text; // Type inference with var var number = 42; // Compiler infers int var name = "Bob"; // Compiler infers string // Constants const double PI = 3.14159; const string AppName = "MyApp"; // Read-only fields (runtime constant) readonly DateTime startTime = DateTime.Now;

Control Flow

Conditional Statements

// If-else int score = 85; if (score >= 90) { Console.WriteLine("Grade: A"); } else if (score >= 80) { Console.WriteLine("Grade: B"); } else { Console.WriteLine("Grade: C"); } // Ternary operator string result = (score >= 60) ? "Pass" : "Fail"; // Switch statement (traditional) string day = "Monday"; switch (day) { case "Monday": Console.WriteLine("Start of week"); break; case "Friday": Console.WriteLine("End of week"); break; default: Console.WriteLine("Midweek"); break; } // Switch expression (C# 8.0+) string dayType = day switch { "Monday" or "Tuesday" => "Start of week", "Friday" => "End of week", _ => "Midweek" };

Loops

// For loop for (int i = 0; i < 5; i++) { Console.WriteLine($"Count: {i}"); } // While loop int counter = 0; while (counter < 5) { Console.WriteLine($"Counter: {counter}"); counter++; } // Do-while loop int num = 0; do { Console.WriteLine($"Number: {num}"); num++; } while (num < 5); // Foreach loop string[] fruits = { "Apple", "Banana", "Orange" }; foreach (string fruit in fruits) { Console.WriteLine(fruit); }
graph TD A[Start Loop] --> B{Condition?} B -->|True| C[Execute Block] C --> D[Update] D --> B B -->|False| E[Exit Loop]

Methods

Methods are blocks of code that perform specific tasks and can be reused.

// Method with no return value void PrintMessage(string message) { Console.WriteLine(message); } // Method with return value int Add(int a, int b) { return a + b; } // Method with optional parameters void Greet(string name, string greeting = "Hello") { Console.WriteLine($"{greeting}, {name}!"); } // Method with named parameters Greet(greeting: "Hi", name: "Alice"); // Expression-bodied method (C# 6.0+) int Multiply(int x, int y) => x * y; // Method overloading int Calculate(int a, int b) => a + b; double Calculate(double a, double b) => a + b; string Calculate(string a, string b) => a + b;

Classes and Objects

Classes are blueprints for creating objects.

public class Person { // Fields (private by convention) private string name; private int age; // Properties (public access) public string Name { get { return name; } set { name = value; } } // Auto-implemented property public int Age { get; set; } // Constructor public Person(string name, int age) { this.name = name; this.age = age; } // Method public void Introduce() { Console.WriteLine($"Hi, I'm {name} and I'm {age} years old."); } } // Creating and using objects Person person = new Person("Alice", 30); person.Introduce(); Console.WriteLine($"Name: {person.Name}"); // Object initializer syntax Person person2 = new Person("Bob", 25) { Age = 26 };

Namespaces

Namespaces organize code and prevent naming conflicts.

namespace MyApplication.Models { public class User { public string Username { get; set; } } } namespace MyApplication.Services { using MyApplication.Models; public class UserService { public User GetUser(string username) { return new User { Username = username }; } } } // Using declarations using System; using System.Collections.Generic; using MyApplication.Services;

Exception Handling

Exception handling manages runtime errors gracefully.

try { int result = Divide(10, 0); } catch (DivideByZeroException ex) { Console.WriteLine($"Error: {ex.Message}"); } catch (Exception ex) { Console.WriteLine($"Unexpected error: {ex.Message}"); } finally { Console.WriteLine("Cleanup code runs regardless"); } // Throwing exceptions int Divide(int a, int b) { if (b == 0) { throw new DivideByZeroException("Cannot divide by zero"); } return a / b; }
sequenceDiagram participant Code participant Try Block participant Catch Block participant Finally Block Code->>Try Block: Execute code alt Exception Occurs Try Block->>Catch Block: Throw exception Catch Block->>Catch Block: Handle exception else No Exception Try Block->>Try Block: Complete normally end Try Block->>Finally Block: Always execute Finally Block->>Code: Return control

Collections

C# provides various collection types for storing groups of objects.

using System.Collections.Generic; // List (dynamic array) List<string> names = new List<string>(); names.Add("Alice"); names.Add("Bob"); names.Remove("Alice"); int count = names.Count; // Dictionary (key-value pairs) Dictionary<string, int> ages = new Dictionary<string, int>(); ages["Alice"] = 30; ages["Bob"] = 25; int aliceAge = ages["Alice"]; // HashSet (unique values) HashSet<int> uniqueNumbers = new HashSet<int>(); uniqueNumbers.Add(1); uniqueNumbers.Add(1); // Duplicate ignored bool contains = uniqueNumbers.Contains(1); // Queue (FIFO) Queue<string> queue = new Queue<string>(); queue.Enqueue("First"); queue.Enqueue("Second"); string first = queue.Dequeue(); // Stack (LIFO) Stack<int> stack = new Stack<int>(); stack.Push(1); stack.Push(2); int top = stack.Pop();

LINQ Basics

Language Integrated Query (LINQ) provides a consistent way to query collections.

using System.Linq; int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // Query syntax var evenNumbers = from n in numbers where n % 2 == 0 select n; // Method syntax var evenNumbers2 = numbers.Where(n => n % 2 == 0); // Common LINQ operations var sum = numbers.Sum(); var average = numbers.Average(); var max = numbers.Max(); var first = numbers.First(); var filtered = numbers.Where(n => n > 5).ToList(); var sorted = numbers.OrderByDescending(n => n);

Practical Example: Simple Console Application

using System; using System.Collections.Generic; using System.Linq; namespace TaskManager { public class Task { public int Id { get; set; } public string Description { get; set; } public bool IsCompleted { get; set; } } public class TaskManager { private List<Task> tasks = new List<Task>(); private int nextId = 1; public void AddTask(string description) { tasks.Add(new Task { Id = nextId++, Description = description, IsCompleted = false }); Console.WriteLine($"Task added: {description}"); } public void CompleteTask(int id) { var task = tasks.FirstOrDefault(t => t.Id == id); if (task != null) { task.IsCompleted = true; Console.WriteLine($"Task completed: {task.Description}"); } } public void ListTasks() { Console.WriteLine("\nTasks:"); foreach (var task in tasks) { string status = task.IsCompleted ? "[X]" : "[ ]"; Console.WriteLine($"{task.Id}. {status} {task.Description}"); } } } class Program { static void Main(string[] args) { var manager = new TaskManager(); manager.AddTask("Learn C# fundamentals"); manager.AddTask("Build a console app"); manager.ListTasks(); manager.CompleteTask(1); manager.ListTasks(); } } }

Key Takeaways