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 int, double, string, 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.