Learning C# Programming

Master modern .NET development with C# - from enterprise applications to Unity games. Build cross-platform applications with one of the most powerful and elegant languages.

Progress: 0% (0/0 sections)

Why Learn C#?

  • Enterprise Ready: C# powers millions of business applications with robust frameworks like ASP.NET Core and Entity Framework
  • Unity Game Development: The primary language for Unity, the world's most popular game engine used by 50% of all games
  • Cross-Platform Power: Build for Windows, Linux, macOS, iOS, Android, and web with .NET 8 and MAUI
  • Modern Language Features: Async/await, LINQ, pattern matching, records, and top-level statements for clean, expressive code
  • Career Opportunities: High demand for C# developers in enterprise, game development, and cloud infrastructure roles

Your Learning Path

Master C# step-by-step with this progressive curriculum:

Fundamentals
2-3 hours
OOP
3-4 hours
LINQ
2-3 hours
Async
3-4 hours
Generics
2 hours
Events
2 hours
Advanced
3-4 hours

Interactive Lessons

Click each lesson to expand. Mark complete as you learn.

Variables, Types & Nullable Types

C# has a unified type system where everything derives from object. Understanding value types, reference types, and nullable types is crucial for writing safe, efficient code.

Value Types vs Reference Types

  • Value types (int, double, bool, struct) store data directly on the stack
  • Reference types (string, class, array) store a reference to heap-allocated data
  • Boxing/Unboxing: Converting value types to object incurs performance cost
// Value types
int age = 25;
double pi = 3.14159;
bool isActive = true;

// Reference types
string name = "Alice";
int[] numbers = { 1, 2, 3, 4, 5 };

// Nullable types (C# 2.0+)
int? nullableAge = null;
if (nullableAge.HasValue)
{
    Console.WriteLine($"Age: {nullableAge.Value}");
}
else
{
    Console.WriteLine("Age not specified");
}

// Null-coalescing operator
int displayAge = nullableAge ?? 0;

// C# 8.0: Nullable reference types
string? possiblyNullName = null; // Explicitly nullable
string guaranteedName = "Bob";   // Never null (compiler warns)

The var Keyword

C# supports type inference with var. The type is determined at compile time:

var count = 10;        // int
var price = 99.99;     // double
var message = "Hello"; // string
var items = new List<string>(); // List<string>
Object-Oriented Programming

C# is a fully object-oriented language with first-class support for classes, inheritance, polymorphism, and interfaces.

Classes and Properties

public class Person
{
    // Auto-implemented properties
    public string Name { get; set; }
    public int Age { get; set; }
    
    // Property with backing field
    private string _email;
    public string Email
    {
        get => _email;
        set => _email = value?.ToLower();
    }
    
    // Read-only property (C# 6.0+)
    public string FullInfo => $"{Name} ({Age})";
    
    // Constructor
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    
    // Method
    public void Introduce()
    {
        Console.WriteLine($"Hi, I'm {Name}");
    }
}

Inheritance and Polymorphism

public class Employee : Person
{
    public string JobTitle { get; set; }
    
    public Employee(string name, int age, string jobTitle)
        : base(name, age)
    {
        JobTitle = jobTitle;
    }
    
    // Override base method
    public override string ToString()
    {
        return $"{Name} - {JobTitle}";
    }
}
LINQ & Collections

LINQ (Language Integrated Query) lets you query collections with SQL-like syntax. It's one of C#'s most powerful features.

var numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

// Query syntax
var evenQuery = from n in numbers
                where n % 2 == 0
                select n;

// Method syntax (preferred in most cases)
var evenMethod = numbers.Where(n => n % 2 == 0);

// Chaining operations
var result = numbers
    .Where(n => n > 3)
    .Select(n => n * 2)
    .OrderByDescending(n => n)
    .ToList();

// Aggregations
int sum = numbers.Sum();
double average = numbers.Average();
int max = numbers.Max();

// GroupBy
var groups = numbers.GroupBy(n => n % 2 == 0 ? "Even" : "Odd");
Async/Await & Task-based Programming

Async/await makes asynchronous programming natural and readable. Essential for I/O-bound operations.

public async Task<string> FetchDataAsync(string url)
{
    using var client = new HttpClient();
    
    // await frees up the thread while waiting
    string result = await client.GetStringAsync(url);
    
    return result;
}

// Using the async method
public async Task ProcessDataAsync()
{
    string data = await FetchDataAsync("https://api.example.com");
    Console.WriteLine(data);
}

// Running multiple tasks concurrently
public async Task<int> ProcessMultipleAsync()
{
    var task1 = FetchDataAsync("url1");
    var task2 = FetchDataAsync("url2");
    var task3 = FetchDataAsync("url3");
    
    // Wait for all to complete
    await Task.WhenAll(task1, task2, task3);
    
    return task1.Result.Length + task2.Result.Length + task3.Result.Length;
}
Generics & Constraints

Generics let you write flexible, reusable code that works with any type while maintaining type safety.

// Generic class
public class Stack<T>
{
    private List<T> items = new List<T>();
    
    public void Push(T item) => items.Add(item);
    public T Pop()
    {
        var item = items[^1];
        items.RemoveAt(items.Count - 1);
        return item;
    }
}

// Generic method with constraints
public T FindMax<T>(List<T> items) where T : IComparable<T>
{
    if (items.Count == 0) throw new InvalidOperationException();
    
    T max = items[0];
    foreach (var item in items)
    {
        if (item.CompareTo(max) > 0)
            max = item;
    }
    return max;
}
Delegates, Events & Pattern Matching

Delegates and events enable loose coupling and event-driven architectures. Pattern matching provides concise type checking.

// Delegate
public delegate void NotifyHandler(string message);

// Event
public class Process
{
    public event NotifyHandler OnComplete;
    
    public void Run()
    {
        // Do work...
        OnComplete?.Invoke("Process complete");
    }
}

// Pattern matching (C# 7.0+)
public string Describe(object obj) => obj switch
{
    int n when n > 0 => "Positive number",
    int n when n < 0 => "Negative number",
    string s => $"String of length {s.Length}",
    null => "Null value",
    _ => "Something else"
};

// Records (C# 9.0+) - immutable data holders
public record Person(string Name, int Age);

Curated GitHub Repositories

Hand-picked repositories to accelerate your C# learning journey.

Loading repositories...

Practice Projects

  • 1. Console Calculator with Exception Handling
    ⏱️ 2-3 hours Beginner

    Build a command-line calculator with proper input validation and exception handling.

    Key Concepts: variables, methods, try/catch, Console I/O
  • 2. Todo List with LINQ Filtering
    ⏱️ 3-4 hours Beginner-Intermediate

    Create a console-based todo manager using collections and LINQ for filtering/sorting.

    Key Concepts: Lists, LINQ, file I/O, object serialization
  • 3. Weather API Client with Async/Await
    ⏱️ 4-5 hours Intermediate

    Build an HTTP client that fetches weather data asynchronously and displays formatted results.

    Key Concepts: HttpClient, async/await, JSON deserialization, error handling
  • 4. ASP.NET Core REST API
    ⏱️ 6-8 hours Intermediate-Advanced

    Create a RESTful API with CRUD operations, Entity Framework Core, and dependency injection.

    Key Concepts: Web APIs, EF Core, repositories, middleware, authentication
  • 5. Unity 2D Platformer Prototype
    ⏱️ 8-10 hours Advanced

    Build a 2D platformer game in Unity with player movement, collision detection, and scoring.

    Key Concepts: Unity scripting, MonoBehaviour, physics, game loops, prefabs

Resources Hub

Your Progress

Check off lessons as you complete them. Your progress is saved locally in your browser.