100 C# practice problems with solutions

Feeling like you understand C# syntax but still struggle to build real applications on your own? That gap between watching and writing can be discouraging—but it disappears with consistent, hands-on practice. This post gives you 100 C# practice problems with clear, step-by-step solutions to help you write code with genuine confidence.

You’ll start with core basics like variables, loops, and arrays, then progress to object-oriented programming, LINQ, collections, exception handling, and working with files. Each problem is written in plain language—try it yourself first, then check the solution and truly understand the why behind the logic.

Why is practice so important? Because coding is a practical skill. Every problem you solve builds muscle memory, sharpens your debugging instincts, and turns abstract concepts into automatic habits. Whether you’re just getting started with C# or preparing for a technical interview, these exercises will make your learning stick and leave you feeling truly ready. Pick a problem, start coding, and experience that amazing “I’m really getting this!” moment.

Also try it: 100 .NET practice problems with solutions

1. Hello World

Write a program that prints “Hello, World!” to the console.

csharp

using System;

class Program {
    static void Main() {
        Console.WriteLine("Hello, World!");
    }
}

2. Sum of Two Numbers

Write a method Sum that takes two integers and returns their sum.

csharp

int Sum(int a, int b) => a + b;

3. Check Even or Odd

Write a method that returns true if a number is even.

csharp

bool IsEven(int n) => n % 2 == 0;

4. Maximum of Three Numbers

csharp

int MaxOfThree(int a, int b, int c) => Math.Max(a, Math.Max(b, c));

5. Reverse a String

csharp

string ReverseString(string input) {
    char[] chars = input.ToCharArray();
    Array.Reverse(chars);
    return new string(chars);
}

6. Palindrome Checker

Check if a string is a palindrome (ignore case and non‑alphanumeric).

csharp

bool IsPalindrome(string s) {
    var clean = new string(s.Where(char.IsLetterOrDigit).ToArray()).ToLower();
    return clean.SequenceEqual(clean.Reverse());
}

7. Count Vowels

Count the number of vowels in a string.

csharp

int CountVowels(string s) => s.Count(c => "aeiouAEIOU".Contains(c));

8. Find the Longest Word

Return the longest word in a sentence.

csharp

string LongestWord(string sentence) =>
    sentence.Split(' ').OrderByDescending(w => w.Length).First();

9. Capitalize First Letter of Each Word

csharp

string CapitalizeWords(string s) =>
    string.Join(" ", s.Split(' ').Select(w => char.ToUpper(w[0]) + w.Substring(1).ToLower()));

10. Truncate String with Ellipsis

csharp

string Truncate(string s, int maxLength) =>
    s.Length > maxLength ? s.Substring(0, maxLength) + "..." : s;

11. Check Anagram

Two strings are anagrams if they contain the same characters with same frequency (case‑insensitive, ignore spaces).

csharp

bool AreAnagrams(string a, string b) {
    var normalize = (string s) => new string(s.ToLower().Where(char.IsLetterOrDigit).OrderBy(c => c).ToArray());
    return normalize(a) == normalize(b);
}

12. String Compression

Compress “aaabbc” to “a3b2c1”.

csharp

string Compress(string s) {
    if (string.IsNullOrEmpty(s)) return "";
    var result = new StringBuilder();
    int count = 1;
    for (int i = 1; i < s.Length; i++) {
        if (s[i] == s[i - 1]) count++;
        else { result.Append($"{s[i-1]}{count}"); count = 1; }
    }
    result.Append($"{s[^1]}{count}");
    return result.ToString();
}

13. Find All Substrings

Print all substrings of a given string.

csharp

void PrintSubstrings(string s) {
    for (int i = 0; i < s.Length; i++)
        for (int j = i; j < s.Length; j++)
            Console.WriteLine(s.Substring(i, j - i + 1));
}

14. Remove Duplicate Characters

csharp

string RemoveDuplicates(string s) => new string(s.Distinct().ToArray());

15. Convert String to Title Case

csharp

string ToTitleCase(string s) => System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

16. Sum of Array Elements

csharp

int SumArray(int[] arr) => arr.Sum();

17. Find Min and Max

Return a tuple with the minimum and maximum.

csharp

(int min, int max) FindMinMax(int[] arr) => (arr.Min(), arr.Max());

18. Remove Negatives from an Array

csharp

int[] RemoveNegatives(int[] arr) => arr.Where(x => x >= 0).ToArray();

19. Reverse Array In-Place

csharp

void ReverseInPlace(int[] arr) {
    for (int i = 0; i < arr.Length / 2; i++)
        (arr[i], arr[arr.Length - 1 - i]) = (arr[arr.Length - 1 - i], arr[i]);
}

20. Merge Two Sorted Arrays

csharp

int[] MergeSorted(int[] a, int[] b) {
    int[] res = new int[a.Length + b.Length];
    int i = 0, j = 0, k = 0;
    while (i < a.Length && j < b.Length)
        res[k++] = a[i] < b[j] ? a[i++] : b[j++];
    while (i < a.Length) res[k++] = a[i++];
    while (j < b.Length) res[k++] = b[j++];
    return res;
}

21. Remove Duplicates from Array

csharp

int[] RemoveDuplicates(int[] arr) => arr.Distinct().ToArray();

22. Rotate Array Right by K

csharp

int[] RotateRight(int[] arr, int k) {
    k %= arr.Length;
    return arr[^k..].Concat(arr[..^k]).ToArray();
}

23. Find Missing Number 1..N

Given array of size N‑1 with distinct numbers from 1 to N.

csharp

int FindMissing(int[] arr, int n) => n * (n + 1) / 2 - arr.Sum();

24. Find Intersection of Two Arrays

csharp

int[] Intersection(int[] a, int[] b) => a.Intersect(b).ToArray();

25. Find Union

csharp

int[] Union(int[] a, int[] b) => a.Union(b).ToArray();

26. Factorial (Recursive)

csharp

long Factorial(int n) => n == 0 ? 1 : n * Factorial(n - 1);

27. Fibonacci Sequence up to N

csharp

int[] Fibonacci(int n) {
    int[] fib = new int[n];
    if (n > 0) fib[0] = 0;
    if (n > 1) fib[1] = 1;
    for (int i = 2; i < n; i++) fib[i] = fib[i - 1] + fib[i - 2];
    return fib;
}

28. Check Prime Number

csharp

bool IsPrime(int n) {
    if (n < 2) return false;
    for (int i = 2; i * i <= n; i++)
        if (n % i == 0) return false;
    return true;
}

29. FizzBuzz

Print numbers 1–100; multiples of 3 “Fizz”, of 5 “Buzz”, of both “FizzBuzz”.

csharp

void FizzBuzz() {
    for (int i = 1; i <= 100; i++) {
        if (i % 15 == 0) Console.WriteLine("FizzBuzz");
        else if (i % 3 == 0) Console.WriteLine("Fizz");
        else if (i % 5 == 0) Console.WriteLine("Buzz");
        else Console.WriteLine(i);
    }
}

30. Binary Search (Sorted Array)

csharp

int BinarySearch(int[] arr, int target) {
    int left = 0, right = arr.Length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] == target) return mid;
        if (arr[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    return -1;
}

31. Bubble Sort

csharp

void BubbleSort(int[] arr) {
    for (int i = 0; i < arr.Length - 1; i++)
        for (int j = 0; j < arr.Length - i - 1; j++)
            if (arr[j] > arr[j + 1])
                (arr[j], arr[j + 1]) = (arr[j + 1], arr[j]);
}

32. QuickSort (Lomuto)

csharp

void QuickSort(int[] arr, int low, int high) {
    if (low < high) {
        int p = Partition(arr, low, high);
        QuickSort(arr, low, p - 1);
        QuickSort(arr, p + 1, high);
    }
}
int Partition(int[] arr, int low, int high) {
    int pivot = arr[high], i = low - 1;
    for (int j = low; j < high; j++)
        if (arr[j] < pivot) { i++; (arr[i], arr[j]) = (arr[j], arr[i]); }
    (arr[i + 1], arr[high]) = (arr[high], arr[i + 1]);
    return i + 1;
}

33. Linear Search

csharp

int LinearSearch(int[] arr, int target) => Array.IndexOf(arr, target);

34. Count Occurrences of an Element

csharp

int CountOccurrences(int[] arr, int val) => arr.Count(x => x == val);

35. Find Largest Element in 2D Array

csharp

int Max2D(int[,] matrix) {
    int max = matrix[0, 0];
    foreach (int item in matrix) if (item > max) max = item;
    return max;
}

36. Create a Class Person

With properties Name and Age. Add a constructor and a method Introduce.

csharp

public class Person {
    public string Name { get; set; }
    public int Age { get; set; }
    public Person(string name, int age) { Name = name; Age = age; }
    public string Introduce() => $"Hi, I'm {Name}, {Age} years old.";
}

37. Static Utility Class

csharp

public static class MathUtils {
    public static double PI = 3.14159;
    public static double Square(double x) => x * x;
}

38. Inheritance – Employee : Person

Add Salary property and override Introduce.

csharp

public class Employee : Person {
    public decimal Salary { get; set; }
    public Employee(string name, int age, decimal salary) : base(name, age) => Salary = salary;
    public override string Introduce() => base.Introduce() + $" I earn {Salary:C}.";
}

39. Polymorphism – Shape Hierarchy

Abstract class Shape with abstract method GetArea(). Derived Circle and Rectangle.

csharp

public abstract class Shape { public abstract double GetArea(); }
public class Circle : Shape {
    public double Radius { get; set; }
    public override double GetArea() => Math.PI * Radius * Radius;
}
public class Rectangle : Shape {
    public double Width { get; set; }
    public double Height { get; set; }
    public override double GetArea() => Width * Height;
}

40. Interface IDriveable with methods StartStopMove.

csharp

public interface IDriveable {
    void Start();
    void Stop();
    void Move();
}
public class Car : IDriveable {
    public void Start() => Console.WriteLine("Car started.");
    public void Stop() => Console.WriteLine("Car stopped.");
    public void Move() => Console.WriteLine("Car moving.");
}

41. Multiple Interface Implementation

csharp

public interface IWalkable { void Walk(); }
public interface ISwimmable { void Swim(); }
public class Duck : IWalkable, ISwimmable {
    public void Walk() => Console.WriteLine("Duck walks.");
    public void Swim() => Console.WriteLine("Duck swims.");
}

42. Abstract Base Class with Virtual Method

csharp

public abstract class Animal {
    public virtual void Speak() => Console.WriteLine("Animal sound");
}
public class Dog : Animal {
    public override void Speak() => Console.WriteLine("Woof");
}

43. Sealed Class

csharp

public sealed class FinalClass { /* cannot be inherited */ }

44. Properties with Backing Fields

csharp

public class Product {
    private decimal price;
    public decimal Price {
        get => price;
        set { if (value >= 0) price = value; }
    }
}

45. Indexer in Class

csharp

public class StringCollection {
    private List<string> items = new();
    public string this[int index] {
        get => items[index];
        set => items[index] = value;
    }
    public void Add(string item) => items.Add(item);
}

46. Constructor Overloading

csharp

public class Point {
    public int X, Y;
    public Point() : this(0, 0) { }
    public Point(int x, int y) { X = x; Y = y; }
}

47. Destructor / Finalizer

csharp

public class ResourceHolder {
    ~ResourceHolder() => Console.WriteLine("Finalizer called.");
}

48. Method Overloading

csharp

public class MathOps {
    public int Add(int a, int b) => a + b;
    public double Add(double a, double b) => a + b;
    public string Add(string a, string b) => a + b;
}

49. Operator Overloading (+)

csharp

public class Vector {
    public int X, Y;
    public Vector(int x, int y) { X = x; Y = y; }
    public static Vector operator +(Vector a, Vector b) => new(a.X + b.X, a.Y + b.Y);
}

50. Record Type (C# 9+)

csharp

public record Customer(string Name, int Age);

51. LINQ – Filter Even Numbers

csharp

var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();

52. LINQ – Select Projection

csharp

var names = people.Select(p => p.Name);

53. LINQ – OrderBy

csharp

var sorted = products.OrderBy(p => p.Price).ToList();

54. LINQ – Group By

csharp

var groups = students.GroupBy(s => s.FieldOfStudy);
foreach (var g in groups)
    Console.WriteLine($"{g.Key}: {g.Count()}");

55. LINQ – Join (Inner)

csharp

var joined = from p in people
             join a in addresses on p.Id equals a.PersonId
             select new { p.Name, a.City };

56. LINQ – FirstOrDefault

csharp

var firstAdult = people.FirstOrDefault(p => p.Age >= 18);

57. LINQ – Any & All

csharp

bool hasMinors = people.Any(p => p.Age < 18);
bool allAdults = people.All(p => p.Age >= 18);

58. LINQ – Distinct and Count

csharp

int uniqueCities = addresses.Select(a => a.City).Distinct().Count();

59. LINQ – Take/Skip (Pagination)

csharp

var page = items.Skip((pageNo - 1) * pageSize).Take(pageSize);

60. LINQ – Aggregate (Sum, Average, Max)

csharp

double avg = salaries.Average();
decimal total = prices.Sum();

61. Simple Delegate

csharp

delegate int Operation(int a, int b);
// Usage:
Operation add = (x, y) => x + y;
Console.WriteLine(add(2,3));

62. Func and Action

csharp

Func<int, int, int> multiply = (x, y) => x * y;
Action<string> print = msg => Console.WriteLine(msg);

63. Predicate Delegate

csharp

Predicate<int> isPositive = n => n > 0;

64. Anonymous Method

csharp

Func<int, int> square = delegate(int x) { return x * x; };

65. Lambda Expressions

csharp

List<int> list = new() { 1,2,3,4,5 };
var squares = list.Select(x => x * x);

66. Event and EventHandler

csharp

public class Button {
    public event EventHandler Clicked;
    public void Press() => Clicked?.Invoke(this, EventArgs.Empty);
}
// subscriber
button.Clicked += (sender, e) => Console.WriteLine("Button clicked!");

67. Multicast Delegate

csharp

Action greet = () => Console.WriteLine("Hello");
greet += () => Console.WriteLine("World");
greet(); // prints Hello and World

68. Closure in Lambdas

csharp

int factor = 2;
Func<int, int> multiplier = x => x * factor;
Console.WriteLine(multiplier(5)); // 10

69. Delegate with Callback

csharp

void Process(int num, Action<int> callback) => callback(num);
Process(5, res => Console.WriteLine(res));

70. Custom EventArgs and Event

csharp

public class CustomEventArgs : EventArgs { public string Message { get; set; } }
public delegate void CustomEventHandler(object sender, CustomEventArgs e);
public class Publisher {
    public event CustomEventHandler OnCustomEvent;
    public void Trigger() => OnCustomEvent?.Invoke(this, new CustomEventArgs { Message = "Event fired" });
}

71. Try-Catch Basic

csharp

try { int x = int.Parse("abc"); }
catch (FormatException ex) { Console.WriteLine(ex.Message); }

72. Multiple Catch Blocks

csharp

try { /* ... */ }
catch (DivideByZeroException) { /* ... */ }
catch (Exception ex) { Console.WriteLine(ex.Message); }

73. Finally Block

csharp

StreamReader reader = null;
try { reader = File.OpenText("file.txt"); string content = reader.ReadToEnd(); }
finally { reader?.Close(); }

Also try it: 100 C++ practice problems with solutions

74. Using Statement (IDisposable)

csharp

using (var reader = File.OpenText("file.txt")) { Console.WriteLine(reader.ReadToEnd()); }

75. Custom Exception

csharp

public class InvalidAgeException : Exception {
    public InvalidAgeException(string msg) : base(msg) { }
}
throw new InvalidAgeException("Age must be positive.");

76. Read All Lines from a File

csharp

string[] lines = File.ReadAllLines("data.txt");

77. Write Text to File

csharp

File.WriteAllText("output.txt", "Hello, C#");

78. Append to File

csharp

File.AppendAllText("log.txt", DateTime.Now + ": Log entry\n");

79. File Exists Check

csharp

if (File.Exists("input.txt")) Console.WriteLine("File exists.");

80. Read File Line by Line (Stream)

csharp

using var reader = new StreamReader("data.txt");
while (!reader.EndOfStream) Console.WriteLine(reader.ReadLine());

81. Async Method and Await

csharp

async Task<string> DownloadDataAsync(string url) {
    using var http = new HttpClient();
    return await http.GetStringAsync(url);
}

82. Task.WhenAll

csharp

async Task<string[]> FetchMultipleAsync(IEnumerable<string> urls) {
    var tasks = urls.Select(u => new HttpClient().GetStringAsync(u));
    return await Task.WhenAll(tasks);
}

83. Task.Run for CPU-Bound Work

csharp

Task<int> compute = Task.Run(() => {
    int sum = 0;
    for (int i = 0; i < 1000; i++) sum += i;
    return sum;
});
int result = await compute;

84. CancellationToken

csharp

async Task LongRunningAsync(CancellationToken ct) {
    while (!ct.IsCancellationRequested) {
        await Task.Delay(100, ct);
    }
}

85. Async with Timeout

csharp

async Task<string> FetchWithTimeout(string url, int timeoutMs) {
    using var cts = new CancellationTokenSource(timeoutMs);
    return await new HttpClient().GetStringAsync(url, cts.Token);
}

86. Recursive Factorial with Memoization

csharp

Dictionary<int, long> memo = new();
long MemoFactorial(int n) {
    if (n <= 1) return 1;
    if (memo.ContainsKey(n)) return memo[n];
    memo[n] = n * MemoFactorial(n - 1);
    return memo[n];
}

87. Stack Implementation

csharp

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

88. Queue Implementation

csharp

public class Queue<T> {
    private LinkedList<T> list = new();
    public void Enqueue(T item) => list.AddLast(item);
    public T Dequeue() { T item = Peek(); list.RemoveFirst(); return item; }
    public T Peek() => list.First.Value;
    public int Count => list.Count;
}

89. Singly Linked List Node

csharp

public class Node<T> {
    public T Data { get; set; }
    public Node<T> Next { get; set; }
    public Node(T data) => Data = data;
}

90. Reverse a Singly Linked List

csharp

Node<T> ReverseList<T>(Node<T> head) {
    Node<T> prev = null, current = head;
    while (current != null) {
        Node<T> next = current.Next;
        current.Next = prev;
        prev = current;
        current = next;
    }
    return prev;
}

Also try it: 100 Azure practice problems with solutions

91. Find Length of Linked List

csharp

int Length<T>(Node<T> head) {
    int count = 0;
    while (head != null) { count++; head = head.Next; }
    return count;
}

92. Palindrome Linked List

csharp

bool IsPalindrome(Node<char> head) {
    var stack = new Stack<char>();
    var slow = head; var fast = head;
    while (fast != null && fast.Next != null) {
        stack.Push(slow.Data);
        slow = slow.Next;
        fast = fast.Next.Next;
    }
    if (fast != null) slow = slow.Next; // odd length
    while (slow != null) {
        if (stack.Pop() != slow.Data) return false;
        slow = slow.Next;
    }
    return true;
}

93. Binary Tree Node and In-Order Traversal

csharp

public class TreeNode {
    public int Val;
    public TreeNode Left, Right;
    public TreeNode(int val) => Val = val;
}
void InOrder(TreeNode root) {
    if (root == null) return;
    InOrder(root.Left);
    Console.Write(root.Val + " ");
    InOrder(root.Right);
}

94. Find Height of Binary Tree

csharp

int Height(TreeNode root) {
    if (root == null) return 0;
    return 1 + Math.Max(Height(root.Left), Height(root.Right));
}

95. Check if Binary Tree is Mirror (Symmetric)

csharp

bool IsSymmetric(TreeNode root) => IsMirror(root, root);
bool IsMirror(TreeNode t1, TreeNode t2) {
    if (t1 == null && t2 == null) return true;
    if (t1 == null || t2 == null) return false;
    return (t1.Val == t2.Val) && IsMirror(t1.Left, t2.Right) && IsMirror(t1.Right, t2.Left);
}

96. Generate Permutations of a String

csharp

void Permute(string s, int l, int r) {
    if (l == r) Console.WriteLine(s);
    else {
        char[] arr = s.ToCharArray();
        for (int i = l; i <= r; i++) {
            (arr[l], arr[i]) = (arr[i], arr[l]);
            Permute(new string(arr), l + 1, r);
            (arr[l], arr[i]) = (arr[i], arr[l]); // backtrack
        }
    }
}

97. Binary Search Tree Insertion

csharp

TreeNode InsertBST(TreeNode root, int val) {
    if (root == null) return new TreeNode(val);
    if (val < root.Val) root.Left = InsertBST(root.Left, val);
    else root.Right = InsertBST(root.Right, val);
    return root;
}

98. Check if Two Strings are One Edit Away

csharp

bool OneEditAway(string a, string b) {
    int m = a.Length, n = b.Length;
    if (Math.Abs(m - n) > 1) return false;
    int i = 0, j = 0, edits = 0;
    while (i < m && j < n) {
        if (a[i] != b[j]) {
            if (++edits > 1) return false;
            if (m > n) i++;
            else if (m < n) j++;
            else { i++; j++; }
        } else { i++; j++; }
    }
    if (i < m || j < n) edits++;
    return edits <= 1;
}

99. LRU Cache (Simplified using LinkedList and Dictionary)

csharp

public class LRUCache {
    private record CacheItem(int Key, int Value);
    private LinkedList<CacheItem> list = new();
    private Dictionary<int, LinkedListNode<CacheItem>> map = new();
    private int capacity;
    public LRUCache(int capacity) => this.capacity = capacity;
    public int Get(int key) {
        if (!map.ContainsKey(key)) return -1;
        var node = map[key];
        list.Remove(node); list.AddFirst(node);
        return node.Value.Value;
    }
    public void Put(int key, int value) {
        if (map.ContainsKey(key)) {
            var node = map[key];
            list.Remove(node);
            list.AddFirst(new LinkedListNode<CacheItem>(new CacheItem(key, value)));
            map[key] = list.First;
            return;
        }
        if (map.Count >= capacity) {
            var last = list.Last; map.Remove(last.Value.Key); list.RemoveLast();
        }
        var newNode = new LinkedListNode<CacheItem>(new CacheItem(key, value));
        list.AddFirst(newNode);
        map[key] = newNode;
    }
}

100. Simple Dependency Injection Container

csharp

public class DIContainer {
    private Dictionary<Type, Type> registrations = new();
    public void Register<TInterface, TImplementation>() where TImplementation : TInterface =>
        registrations[typeof(TInterface)] = typeof(TImplementation);
    public TInterface Resolve<TInterface>() {
        var type = registrations[typeof(TInterface)];
        return (TInterface)Activator.CreateInstance(type);
    }
}

Conclusion: Turning Effort into C# Confidence

Working through these 100 C# practice problems with solutions is a powerful achievement. Each problem you completed added a new layer to your understanding of programming logic, object-oriented concepts, and problem-solving skills.

There may have been moments of confusion or frustration, but those moments are what shape real developers. Every error fixed and every solution understood is proof that your skills are growing stronger with time.

C# is a language built for creating strong and reliable applications, and with consistent practice like this, you are building the foundation to create something meaningful in the future. Keep challenging yourself, keep writing code, and remember—progress comes from persistence, not perfection.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top