100 .NET practice problems with solutions

Are you looking to sharpen your .NET skills, ace a technical interview, or simply build confidence with real-world coding? You’ve landed in the right place. This post brings together 100 carefully curated .NET practice problems with solutions — from beginner-friendly C# exercises to advanced challenges in ASP.NET Core, LINQ, Entity Framework, and more. Each problem comes with a clear explanation and a ready-to-run solution, so you can learn by doing and review concepts at your own pace.

Whether you’re a self-taught developer or an experienced engineer preparing for your next role, these .NET coding exercises will help you write cleaner, more efficient code. Dive in, pick a problem, and start practicing today.

Try it: 100 C++ practice problems with solutions

1. Hello World Console App

Write a console application that prints “Hello, .NET!”.

csharp

// Program.cs (top-level statements)
Console.WriteLine("Hello, .NET!");

2. Read User Input

Read a name from the console and print a greeting.

csharp

Console.Write("Enter your name: ");
string name = Console.ReadLine();
Console.WriteLine($"Hello, {name}!");

3. Variables and Data Types

Declare an intdoublestring, and bool variable, assign values, and print them.

csharp

int age = 30;
double price = 19.99;
string city = "New York";
bool isActive = true;
Console.WriteLine($"{age}, {price}, {city}, {isActive}");

4. String Interpolation

Combine three strings into a full sentence using interpolation.

csharp

string firstName = "Alice";
string lastName = "Smith";
int year = 2025;
Console.WriteLine($"{firstName} {lastName} joined in {year}.");

5. Simple Math Operations

Add, subtract, multiply, and divide two numbers.

csharp

int a = 10, b = 3;
Console.WriteLine($"Add: {a + b}, Subtract: {a - b}, Multiply: {a * b}, Divide: {a / (double)b:F2}");

6. If-Else Statement

Check if a number is positive, negative, or zero.

csharp

int number = -5;
if (number > 0) Console.WriteLine("Positive");
else if (number < 0) Console.WriteLine("Negative");
else Console.WriteLine("Zero");

7. Switch Statement

Convert a day number (1–7) to day name.

csharp

int day = 3;
switch (day)
{
    case 1: Console.WriteLine("Monday"); break;
    case 2: Console.WriteLine("Tuesday"); break;
    case 3: Console.WriteLine("Wednesday"); break;
    // ... other cases
    default: Console.WriteLine("Invalid"); break;
}

8. For Loop

Print numbers from 1 to 10.

csharp

for (int i = 1; i <= 10; i++)
    Console.Write($"{i} ");

9. While Loop

Repeat until user enters “exit”.

csharp

string input = "";
while (input?.ToLower() != "exit")
{
    Console.Write("Enter command: ");
    input = Console.ReadLine();
    Console.WriteLine($"You entered: {input}");
}

10. Array Declaration and Iteration

Create an array of integers, then use foreach to print them.

csharp

int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int num in numbers)
    Console.Write($"{num} ");

11. List<T> Usage

Create a list, add items, remove one, and print count.

csharp

List<string> fruits = new List<string> { "Apple", "Banana" };
fruits.Add("Orange");
fruits.Remove("Banana");
Console.WriteLine($"Count: {fruits.Count}");
fruits.ForEach(f => Console.WriteLine(f));

12. Dictionary Usage

Store ages of people and look up one.

csharp

Dictionary<string, int> ages = new()
{
    ["Alice"] = 25,
    ["Bob"] = 30
};
Console.WriteLine(ages["Alice"]);

13. Method with Parameters and Return

Write a method that calculates area of a rectangle.

csharp

double RectangleArea(double w, double h) => w * h;
Console.WriteLine(RectangleArea(5, 10));

14. Method Overloading

Implement Sum that works for both int and double.

csharp

int Sum(int a, int b) => a + b;
double Sum(double a, double b) => a + b;
Console.WriteLine(Sum(2, 3));
Console.WriteLine(Sum(2.5, 3.7));

15. Class and Object

Define a Person class with Name and Age, then create an instance.

csharp

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person(string name, int age) => (Name, Age) = (name, age);
}
var person = new Person("Alice", 28);
Console.WriteLine($"{person.Name} is {person.Age}");

16. Auto-implemented Properties

Create a Product class with auto-properties and a computed property.

csharp

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public decimal PriceWithTax => Price * 1.2m;
}
var p = new Product { Name = "Book", Price = 10m };
Console.WriteLine(p.PriceWithTax);

17. Constructor Overloading

Rectangle class with default and parameterized constructors.

csharp

public class Rectangle
{
    public double Width { get; }
    public double Height { get; }
    public Rectangle() : this(1, 1) { }
    public Rectangle(double w, double h) => (Width, Height) = (w, h);
}

18. Inheritance

Create a base class Animal and derived Dog.

csharp

public class Animal
{
    public virtual string Sound() => "Some sound";
}
public class Dog : Animal
{
    public override string Sound() => "Woof";
}

19. Polymorphism

Use a list of Animal and call Sound().

csharp

var animals = new List<Animal> { new Dog(), new Animal() };
foreach (var a in animals)
    Console.WriteLine(a.Sound());

20. Abstract Class

Define an abstract class Shape with an abstract method.

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;
}

21. Interface

Define IPrintable with a Print method; implement in Invoice.

csharp

public interface IPrintable { void Print(); }
public class Invoice : IPrintable
{
    public void Print() => Console.WriteLine("Invoice printed");
}

22. Static Class and Methods

Create a static utility class with a method.

csharp

public static class MathUtils
{
    public static double Square(double x) => x * x;
}
Console.WriteLine(MathUtils.Square(5));

23. Extension Methods

Add an extension method to string that reverses it.

csharp

public static class StringExtensions
{
    public static string Reverse(this string s) => new(s.Reverse().ToArray());
}
Console.WriteLine("hello".Reverse());

24. Exception Handling

Use try-catch-finally to handle division by zero.

csharp

try
{
    int result = 10 / int.Parse("0");
}
catch (DivideByZeroException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
finally
{
    Console.WriteLine("This always runs");
}

25. Using Statement (IDisposable)

Use StreamWriter to write to a file, ensuring proper disposal.

csharp

using var writer = new StreamWriter("output.txt");
writer.WriteLine("Hello, file!");

26. File Read and Write

Read all lines from a file and print them.

csharp

string[] lines = File.ReadAllLines("input.txt");
foreach (var line in lines)
    Console.WriteLine(line);

27. Async Method with HttpClient

Make an HTTP GET request and print content length.

csharp

using var client = new HttpClient();
string content = await client.GetStringAsync("https://example.com");
Console.WriteLine($"Length: {content.Length}");

28. LINQ Query on List

Given a list of integers, filter even numbers and sort descending.

csharp

var numbers = new List<int> { 5, 2, 9, 1, 5, 6 };
var result = numbers.Where(n => n % 2 == 0).OrderByDescending(n => n);
result.ToList().ForEach(n => Console.WriteLine(n));

29. Lambda Expressions

Use a lambda to filter a list of strings by length.

csharp

var words = new[] { "apple", "pear", "kiwi" };
var shortWords = words.Where(w => w.Length <= 4).ToList();

30. Delegate

Declare a delegate and use it to reference two methods.

csharp

delegate int Operation(int a, int b);
Operation add = (a, b) => a + b;
Operation multiply = (a, b) => a * b;
Console.WriteLine(add(2,3)); // 5

31. Events

Create a Button class with a Click event.

csharp

public class Button
{
    public event EventHandler Click;
    public void OnClick() => Click?.Invoke(this, EventArgs.Empty);
}
var btn = new Button();
btn.Click += (s, e) => Console.WriteLine("Button clicked!");
btn.OnClick();

Try it: 100 Ruby practice problems with solutions

32. Generic Method

Write a method that swaps two values.

csharp

void Swap<T>(ref T a, ref T b) => (a, b) = (b, a);
int x = 1, y = 2;
Swap(ref x, ref y);
Console.WriteLine($"{x} {y}");

33. Nullable Value Types

Handle a nullable int and provide default.

csharp

int? maybeNumber = null;
Console.WriteLine(maybeNumber ?? 0);

34. String Manipulation

Split a sentence into words, then join with hyphens.

csharp

string sentence = "I am learning .NET";
string[] words = sentence.Split(' ');
Console.WriteLine(string.Join('-', words));

35. DateTime Parsing

Parse a date string and add one month.

csharp

string dateStr = "2025-03-15";
DateTime date = DateTime.Parse(dateStr);
Console.WriteLine(date.AddMonths(1).ToString("yyyy-MM-dd"));

36. Regular Expressions

Extract all email addresses from a text.

csharp

string text = "Contact: alice@example.com or bob@test.org";
var matches = Regex.Matches(text, @"[\w\.-]+@[\w\.-]+\.\w+");
foreach (Match match in matches)
    Console.WriteLine(match.Value);

37. JSON Serialization

Serialize an object to JSON string using System.Text.Json.

csharp

var person = new Person("Alice", 30);
string json = JsonSerializer.Serialize(person);
Console.WriteLine(json);

38. HttpClient POST

Send a POST request with JSON body.

csharp

using var client = new HttpClient();
var content = new StringContent(JsonSerializer.Serialize(new { name = "test" }), Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://httpbin.org/post", content);
Console.WriteLine(await response.Content.ReadAsStringAsync());

39. Minimal API (Hello World)

Create a minimal API that returns “Hello API” at GET “/”.

csharp

// Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello API");
app.Run();

40. Minimal API with Parameter

Return a greeting with a name query parameter.

csharp

app.MapGet("/hello", (string name = "World") => $"Hello, {name}!");

41. Controller-based Web API

Create a controller with a GET endpoint returning a list of strings.

csharp

[ApiController]
[Route("api/[controller]")]
public class ValuesController : ControllerBase
{
    [HttpGet]
    public IEnumerable<string> Get() => new[] { "value1", "value2" };
}

42. Dependency Injection

Register a service and inject it into a minimal API handler.

csharp

builder.Services.AddScoped<IMyService, MyService>();
app.MapGet("/data", (IMyService svc) => svc.GetData());

public interface IMyService { string GetData(); }
public class MyService : IMyService { public string GetData() => "DI works!"; }

43. Entity Framework Core: DbContext

Define a AppDbContext with a Product entity.

csharp

public class AppDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options.UseSqlServer("connection-string");
}
public class Product { public int Id { get; set; } public string Name { get; set; } }

44. EF Core: Querying Data

Fetch all products from the database.

csharp

using var db = new AppDbContext();
var products = db.Products.ToList();
foreach (var p in products)
    Console.WriteLine(p.Name);

45. EF Core: Insert

Add a new product.

csharp

db.Products.Add(new Product { Name = "New Product" });
db.SaveChanges();

46. EF Core: Update

Update a product’s name.

csharp

var product = db.Products.Find(1);
if (product != null)
{
    product.Name = "Updated";
    db.SaveChanges();
}

47. EF Core: Delete

Remove a product by id.

csharp

var product = db.Products.Find(1);
if (product != null)
{
    db.Products.Remove(product);
    db.SaveChanges();
}

48. Configuration (appsettings.json)

Read a connection string from configuration.

csharp

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");

49. Logging

Inject ILogger and log an information message.

csharp

app.MapGet("/", (ILogger<Program> logger) =>
{
    logger.LogInformation("Home page visited");
    return "Hello";
});

50. Caching with IMemoryCache

Cache the current time and return cached value.

csharp

app.MapGet("/time", (IMemoryCache cache) =>
{
    if (!cache.TryGetValue("now", out string now))
    {
        now = DateTime.Now.ToString();
        cache.Set("now", now, TimeSpan.FromSeconds(10));
    }
    return now;
});

51. Unit Testing with xUnit

Write a test for the Sum method.

csharp

public class Calculator { public int Add(int a, int b) => a + b; }
// Test class
public class CalculatorTests
{
    [Fact]
    public void Add_ReturnsSum()
    {
        var calc = new Calculator();
        Assert.Equal(5, calc.Add(2, 3));
    }
}

52. Mocking with Moq

Mock a service interface in a unit test.

csharp

var mock = new Mock<IWeatherService>();
mock.Setup(s => s.GetTemperature()).Returns(25);
var result = mock.Object.GetTemperature();
Assert.Equal(25, result);

53. Task.WhenAll

Run multiple async operations concurrently.

csharp

async Task<string> FetchUrl(string url) { using var client = new HttpClient(); return await client.GetStringAsync(url); }
var urls = new[] { "https://example.com", "https://httpbin.org/get" };
var results = await Task.WhenAll(urls.Select(FetchUrl));

54. Parallel.ForEach

Process a collection in parallel.

csharp

var items = Enumerable.Range(1, 100);
Parallel.ForEach(items, item =>
{
    Console.WriteLine($"Processed {item} on thread {Environment.CurrentManagedThreadId}");
});

55. Lock Statement for Thread Safety

Protect a shared counter with lock.

csharp

object locker = new();
int count = 0;
Parallel.For(0, 100, _ =>
{
    lock (locker) { count++; }
});
Console.WriteLine(count);

56. Channel<T> (Producer-Consumer)

Use System.Threading.Channels to send data between tasks.

csharp

var channel = Channel.CreateUnbounded<int>();
var producer = Task.Run(async () =>
{
    for (int i = 0; i < 5; i++)
        await channel.Writer.WriteAsync(i);
    channel.Writer.Complete();
});
var consumer = Task.Run(async () =>
{
    await foreach (var item in channel.Reader.ReadAllAsync())
        Console.WriteLine($"Received {item}");
});
await Task.WhenAll(producer, consumer);

57. Record Types

Define a Person record and create instances.

csharp

public record Person(string Name, int Age);
var p1 = new Person("Alice", 30);
var p2 = p1 with { Age = 31 };
Console.WriteLine(p2);

58. Pattern Matching (Type)

Check an object’s type and cast.

csharp

object obj = "hello";
if (obj is string str)
    Console.WriteLine(str.ToUpper());

59. Positional Pattern

Deconstruct a tuple with pattern matching.

csharp

(string city, int? zip) input = ("Paris", 75001);
var description = input switch
{
    ("Paris", > 75000) => "Paris, old district",
    (_, null) => "No zip",
    _ => "Other"
};

60. Switch Expression

Transform a number grade to a letter grade.

csharp

int score = 85;
string grade = score switch
{
    >= 90 => "A",
    >= 80 => "B",
    >= 70 => "C",
    _ => "F"
};
Console.WriteLine(grade);

61. Null-Conditional Operators

Access a property on a possibly null object.

csharp

Person p = null;
Console.WriteLine(p?.Name ?? "unknown");

62. Null-Coalescing Assignment

Assign a value only if variable is null.

csharp

string name = null;
name ??= "Default";
Console.WriteLine(name);

63. Using Declarations (C# 8+)

Use a using declaration for file stream.

csharp

using var stream = new FileStream("data.txt", FileMode.Open);
// stream disposed at end of scope

64. Index and Range (C# 8)

Get the last element and a slice of an array.

csharp

int[] arr = { 1, 2, 3, 4, 5 };
Console.WriteLine(arr[^1]);   // 5
int[] slice = arr[1..^1];    // 2,3,4

65. Top-Level Statements

Write a complete program without explicit Main method.

csharp

// Program.cs (no namespace/class needed)
Console.WriteLine("Top-level program");

66. Implicit Using Directives

In a new .NET project, automatically included namespaces. No code needed, just mention.

Try it: 100 Python practice problems with solutions

67. Global Usings

Add a global using directive in a separate file (e.g., GlobalUsings.cs).

csharp

global using System;
global using System.Collections.Generic;

68. File-Scoped Namespace

Define a namespace for a whole file.

csharp

namespace MyApp;
public class Example { }

69. Init-Only Properties

Make a property settable only during initialization.

csharp

public class Config { public string Key { get; init; } }
var config = new Config { Key = "abc" };
// config.Key = "xyz"; // error

70. Required Members (C# 11)

Mark a property as required to enforce initialization.

csharp

public class User { public required string Name { get; init; } }
var user = new User { Name = "Alice" };

71. Primary Constructors (C# 12)

Define constructor parameters directly on class declaration.

csharp

public class Person(string name, int age)
{
    public string Name => name;
    public int Age => age;
}
var p = new Person("Bob", 25);
Console.WriteLine(p.Name);

72. Collection Expressions (C# 12)

Use new syntax for creating collections.

csharp

int[] numbers = [1, 2, 3, 4];
List<string> names = ["Alice", "Bob"];

73. Lambda Improvements (C# 10)

Lambdas with natural return types and attributes.

csharp

var parse = (string s) => int.Parse(s);

74. Span<T> Usage

Manipulate a portion of an array without allocations.

csharp

int[] data = { 1, 2, 3, 4, 5 };
Span<int> span = data.AsSpan(1, 3);
span[0] = 42;
Console.WriteLine(data[1]); // 42

75. Memory-Efficient String Handling

Use Span<char> to slice a string.

csharp

ReadOnlySpan<char> text = "Hello, World!";
var slice = text[7..12]; // "World"
Console.WriteLine(slice.ToString());

76. Unsafe Code (Pointers)

Use a fixed block to access array elements with pointers.

csharp

unsafe
{
    int[] arr = { 10, 20, 30 };
    fixed (int* ptr = arr)
    {
        Console.WriteLine(*ptr);
    }
}

(Require <AllowUnsafeBlocks>true</AllowUnsafeBlocks> in csproj)

77. Unsafe API via Marshal

Copy data from unmanaged memory.

csharp

IntPtr ptr = Marshal.AllocHGlobal(4);
Marshal.WriteInt32(ptr, 99);
int val = Marshal.ReadInt32(ptr);
Marshal.FreeHGlobal(ptr);

78. P/Invoke (Windows)

Call MessageBox from user32.dll.

csharp

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);
MessageBox(IntPtr.Zero, "Hello", ".NET", 0);

79. BackgroundService (IHostedService)

Create a hosted service that logs every 5 seconds.

csharp

public class TimedBackgroundService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            Console.WriteLine("Background work at: " + DateTimeOffset.Now);
            await Task.Delay(5000, stoppingToken);
        }
    }
}
// Register: services.AddHostedService<TimedBackgroundService>();

Try it: 100 C# practice problems with solutions

80. Options Pattern

Bind configuration section to a strongly typed class.

csharp

builder.Services.Configure<MySettings>(builder.Configuration.GetSection("MySettings"));
// Usage
app.MapGet("/config", (IOptions<MySettings> opt) => opt.Value.SomeSetting);
public class MySettings { public string SomeSetting { get; set; } }

81. Health Checks

Add a simple health check endpoint.

csharp

builder.Services.AddHealthChecks();
app.MapHealthChecks("/health");

82. Rate Limiting (ASP.NET Core 8+)

Limit an endpoint to 10 requests per minute.

csharp

using System.Threading.RateLimiting;
builder.Services.AddRateLimiter(options =>
{
    options.AddFixedWindowLimiter("fixed", lim =>
    {
        lim.PermitLimit = 10;
        lim.Window = TimeSpan.FromMinutes(1);
    });
});
app.MapGet("/limited", () => "OK").RequireRateLimiting("fixed");

83. Output Caching

Cache the response of an endpoint for 30 seconds.

csharp

builder.Services.AddOutputCache();
app.UseOutputCache();
app.MapGet("/cached", () => DateTime.Now.ToString()).CacheOutput(p => p.Expire(TimeSpan.FromSeconds(30)));

84. Minimal API with OpenAPI (Swagger)

Enable Swagger UI in a minimal API project.

csharp

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
app.UseSwagger();
app.UseSwaggerUI();

85. SignalR Hub

Create a simple chat hub and broadcast messages.

csharp

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
// Register: builder.Services.AddSignalR(); app.MapHub<ChatHub>("/chathub");

86. gRPC Service

Define a proto file and implement the service.

protobuf

service Greeter { rpc SayHello (HelloRequest) returns (HelloReply); }
message HelloRequest { string name = 1; }
message HelloReply { string message = 1; }

csharp

public class GreeterService : Greeter.GreeterBase
{
    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        => Task.FromResult(new HelloReply { Message = $"Hello, {request.Name}" });
}

87. JWT Authentication

Set up JWT bearer authentication and protect an endpoint.

csharp

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(opt => {
        opt.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "your-issuer",
            ValidAudience = "your-audience",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-secret-key"))
        };
    });
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/secure", [Authorize] () => "Secret data");

88. Custom Authorization Policy

Create a policy requiring a specific claim.

csharp

builder.Services.AddAuthorization(options =>
    options.AddPolicy("AdminOnly", policy => policy.RequireClaim("role", "admin")));
app.MapGet("/admin", [Authorize(Policy = "AdminOnly")] () => "Admin area");

89. Custom Middleware for Exception Handling

Catch all unhandled exceptions and return a 500.

csharp

app.Use(async (context, next) =>
{
    try { await next(); }
    catch (Exception ex)
    {
        context.Response.StatusCode = 500;
        await context.Response.WriteAsync($"Error: {ex.Message}");
    }
});

90. Serilog Integration

Replace default logger with Serilog.

csharp

builder.Host.UseSerilog((ctx, lc) => lc.WriteTo.Console().WriteTo.File("log.txt"));

91. FluentValidation

Validate an input DTO using FluentValidation.

csharp

public class CreateUserRequest { public string Name { get; set; } }
public class CreateUserValidator : AbstractValidator<CreateUserRequest>
{
    public CreateUserValidator() { RuleFor(x => x.Name).NotEmpty().WithMessage("Name required"); }
}
// In endpoint: app.MapPost("/users", async (CreateUserRequest req, IValidator<CreateUserRequest> validator) => {
//    var result = await validator.ValidateAsync(req);
//    if (!result.IsValid) return Results.BadRequest(result.Errors);
//    return Results.Ok("Created");
// });

92. AutoMapper

Map between User entity and UserDto.

csharp

public class User { public int Id { get; set; } public string FullName { get; set; } }
public class UserDto { public string Name { get; set; } }
var config = new MapperConfiguration(cfg => cfg.CreateMap<User, UserDto>().ForMember(d => d.Name, o => o.MapFrom(s => s.FullName)));
var mapper = config.CreateMapper();
var dto = mapper.Map<UserDto>(new User { FullName = "Alice" });

93. MediatR

Implement a request/handler for a query.

csharp

public record GetUserQuery(int Id) : IRequest<UserDto>;
public class GetUserHandler : IRequestHandler<GetUserQuery, UserDto>
{
    public Task<UserDto> Handle(GetUserQuery request, CancellationToken ct) =>
        Task.FromResult(new UserDto { Name = "Alice" });
}
// In endpoint: app.MapGet("/user/{id}", async (int id, IMediator med) => await med.Send(new GetUserQuery(id)));

94. Repository Pattern

Create a generic repository interface and implementation with EF Core.

csharp

public interface IRepository<T> where T : class
{
    Task<T> GetById(int id);
    Task Add(T entity);
}
public class Repository<T> : IRepository<T> where T : class
{
    protected readonly DbContext _db;
    public Repository(DbContext db) => _db = db;
    public async Task<T> GetById(int id) => await _db.Set<T>().FindAsync(id);
    public async Task Add(T entity) { _db.Set<T>().Add(entity); await _db.SaveChangesAsync(); }
}

95. Unit of Work

Coordinate multiple repositories within a transaction.

csharp

public interface IUnitOfWork { IUserRepository Users { get; } Task SaveAsync(); }
public class UnitOfWork : IUnitOfWork
{
    private readonly AppDbContext _db;
    public IUserRepository Users { get; }
    public UnitOfWork(AppDbContext db) { _db = db; Users = new UserRepository(_db); }
    public async Task SaveAsync() => await _db.SaveChangesAsync();
}

96. Specification Pattern

Use a specification to encapsulate query logic.

csharp

public interface ISpecification<T> { Expression<Func<T, bool>> Criteria { get; } }
public class ActiveUsersSpec : ISpecification<User>
{
    public Expression<Func<User, bool>> Criteria => user => user.IsActive;
}
// Usage: var spec = new ActiveUsersSpec(); dbContext.Users.Where(spec.Criteria).ToList();

97. Factory Pattern

Create a payment processor factory.

csharp

public interface IPaymentProcessor { void Process(); }
public class PaypalProcessor : IPaymentProcessor { public void Process() => Console.WriteLine("Paypal"); }
public static class PaymentFactory
{
    public static IPaymentProcessor Create(string type) => type switch
    {
        "paypal" => new PaypalProcessor(),
        _ => throw new NotSupportedException()
    };
}

98. Singleton via DI (Lifetime)

Register a service as singleton.

csharp

builder.Services.AddSingleton<IConfigService, ConfigService>();

99. Background Task Queue

Implement a queue that processes jobs in the background (using Channel).

csharp

public interface IBackgroundTaskQueue { ValueTask QueueAsync(Func<CancellationToken, ValueTask> work); }
public class BackgroundTaskQueue : IBackgroundTaskQueue
{
    private readonly Channel<Func<CancellationToken, ValueTask>> _queue = Channel.CreateUnbounded<Func<CancellationToken, ValueTask>>();
    public async ValueTask QueueAsync(Func<CancellationToken, ValueTask> work) => await _queue.Writer.WriteAsync(work);
    public IAsyncEnumerable<Func<CancellationToken, ValueTask>> DequeueAsync(CancellationToken ct) => _queue.Reader.ReadAllAsync(ct);
}
// Background service consumes it

100. Circuit Breaker with Polly

Implement a resilient HTTP call that breaks after 3 failures.

csharp

var cb = Policy
    .Handle<HttpRequestException>()
    .CircuitBreakerAsync(3, TimeSpan.FromSeconds(30));
await cb.ExecuteAsync(async () =>
{
    var client = new HttpClient();
    await client.GetStringAsync("https://example.com");
});

Final Thought

And just like that, you’ve walked through 100 .NET problems — not perfectly, perhaps, but truthfully. And that, dear learner, is exactly enough.

It’s okay if some solutions took longer to click. It’s okay if a few concepts still feel tender. Growth doesn’t demand flawlessness; it simply asks you to show up, and you did — again and again. I see the quiet dedication behind every line of C# and .NET you typed. I see the late evenings, the furrowed brow, the small sigh of relief when the console finally printed exactly what you hoped for. That gentle persistence is something to cherish, not dismiss.

This post was made with care. Not just to teach you .NET, but to hold space for you while you learned — to remind you that every great developer was once exactly where you are right now: brave enough to learn, soft enough to stumble, and strong enough to keep going. The .NET ecosystem is vast, but you no longer face it as a stranger. You’ve built a foundation laced with patience, curiosity, and a kind heart towards your own progress.

Bookmark this page like a warm, caring companion. Return to it whenever self-doubt whispers — not to prove you remember everything, but to remind yourself how deeply capable you truly are. You are accepted here. You are celebrated. And you are held in high regard, exactly as the developer you are today. Keep coding, keep caring, and keep being wonderfully you.

Leave a Comment

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

Scroll to Top