⏳
Loading cheatsheet...
C# features, ASP.NET Core, Entity Framework, dependency injection, middleware, authentication, and cloud deployment.
// ── Value Types ──
int age = 30;
double pi = 3.14;
decimal price = 19.99m;
bool active = true;
char letter = 'A';
DateTime now = DateTime.UtcNow;
// Nullable value types
int? maybeNull = null;
int value = maybeNull ?? 0; // null coalescing
if (maybeNull.HasValue) { ... }
// ── Reference Types ──
string name = "Alice";
string? nullable = null; // C# 8+ nullable ref
object obj = new object();
// ── Collections ──
var list = new List<int> { 1, 2, 3, 4, 5 };
var dict = new Dictionary<string, int> {
["Alice"] = 30, ["Bob"] = 25
};
var set = new HashSet<string> { "a", "b", "c" };
var queue = new Queue<int>();
queue.Enqueue(1);
queue.Dequeue(); // 1
// ── LINQ ──
var numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Filtering
var evens = numbers.Where(n => n % 2 == 0);
var large = numbers.Where(n => n > 5);
// Projection
var squares = numbers.Select(n => n * n);
var names = users.Select(u => u.Name);
// Ordering
var sorted = numbers.OrderBy(n => n);
var desc = numbers.OrderByDescending(n => n);
var multi = users.OrderBy(u => u.LastName).ThenBy(u => u.FirstName);
// Aggregation
var sum = numbers.Sum();
var avg = numbers.Average();
var min = numbers.Min();
var max = numbers.Max();
var count = numbers.Count();
var any = numbers.Any(n => n > 5);
var all = numbers.All(n => n > 0);
// Grouping
var grouped = users.GroupBy(u => u.Department)
.Select(g => new { Dept = g.Key, Count = g.Count(), AvgAge = g.Average(u => u.Age) });
// Joining
var result = from u in users
join d in departments on u.DeptId equals d.Id
select new { u.Name, d.DeptName };
// First/Single/Element
var first = numbers.First();
var firstOrDefault = numbers.FirstOrDefault(n => n > 5);
var single = numbers.Single(n => n == 5);
// Skip/Take (pagination)
var page = numbers.Skip(10).Take(5);
// To collection
var array = numbers.ToArray();
var list2 = numbers.ToList();
var lookup = users.ToLookup(u => u.Department);
// Distinct & Union
var unique = numbers.Distinct();
var combined = list1.Union(list2);
var except = list1.Except(list2);| Method | Description |
|---|---|
| .Length | Character count |
| .ToUpper() / .ToLower() | Case conversion |
| .Trim() / .TrimStart() / .TrimEnd() | Whitespace |
| .Contains() | Substring check |
| .Split() | String to array |
| .Join() | Array to string |
| .Replace() | Replace substring |
| .Substring() | Extract substring |
| .IndexOf() / .LastIndexOf() | Find position |
| $"Hello {name}" | Interpolation |
| string.IsNullOrEmpty() | Null or empty check |
| string.IsNullOrWhiteSpace() | Null/empty/whitespace |
| Feature | Version | Example |
|---|---|---|
| Nullable refs | C# 8 | string? name = null |
| Records | C# 9 | record Person(string Name) |
| Pattern matching | C# 7+ | if (obj is int n) |
| Switch expressions | C# 8 | result = x switch { ... } |
| Global usings | C# 10 | global using System |
| File-scoped ns | C# 10 | namespace MyApp; |
| Primary ctors | C# 12 | class Person(string Name) |
| List patterns | C# 11 | [1, .., 3] |
// ── Basic Async ──
public async Task<string> GetDataAsync(string url)
{
using var client = new HttpClient();
var response = await client.GetStringAsync(url);
return response;
}
// ── Call Async Method ──
var data = await GetDataAsync("https://api.example.com");
// ── Fire and Forget (discarding)
_ = GetDataAsync("https://api.example.com");
// ── Parallel Execution ──
var task1 = GetDataAsync(url1);
var task2 = GetDataAsync(url2);
var task3 = GetDataAsync(url3);
await Task.WhenAll(task1, task2, task3);
// Results: task1.Result, task2.Result, task3.Result
// ── Parallel with Results ──
var results = await Task.WhenAll(
urls.Select(url => GetDataAsync(url))
);
// ── Race (first to complete) ──
var first = await Task.WhenAny(task1, task2, task3);
var winner = await first;
// ── Timeout ──
try {
await Task.WhenAny(
GetDataAsync(url),
Task.Delay(TimeSpan.FromSeconds(5))
);
} catch (TimeoutException) { ... }
// ── Cancellation ──
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(30));
try {
var data = await GetDataAsync(url, cts.Token);
} catch (OperationCanceledException) {
Console.WriteLine("Cancelled");
}
// ── Configure Await ──
// .ConfigureAwait(false) - don't capture SynchronizationContext
await Task.Run(() => HeavyWork()).ConfigureAwait(false);
// ── ValueTask (for hot paths) ──
public ValueTask<int> GetCachedAsync(string key)
{
if (_cache.TryGetValue(key, out var value))
return ValueTask.FromResult(value);
return new ValueTask<int>(FetchFromDbAsync(key));
}
// ── IAsyncEnumerable (streaming) ──
public async IAsyncEnumerable<string> StreamDataAsync()
{
for (int i = 0; i < 10; i++)
{
await Task.Delay(100);
yield return $"Item {i}";
}
}
await foreach (var item in StreamDataAsync())
{
Console.WriteLine(item);
}// ── Controller ──
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly AppDbContext _db;
public UsersController(AppDbContext db) => _db = db;
[HttpGet]
public async Task<ActionResult<List<User>>> GetAll()
{
return await _db.Users.ToListAsync();
}
[HttpGet("{id:int}")]
public async Task<ActionResult<User>> Get(int id)
{
var user = await _db.Users.FindAsync(id);
if (user == null) return NotFound();
return user;
}
[HttpPost]
public async Task<ActionResult<User>> Create(CreateUserDto dto)
{
var user = new User { Name = dto.Name, Email = dto.Email };
_db.Users.Add(user);
await _db.SaveChangesAsync();
return CreatedAtAction(nameof(Get), new { id = user.Id }, user);
}
[HttpPut("{id}")]
public async Task<IActionResult> Update(int id, UpdateUserDto dto)
{
var user = await _db.Users.FindAsync(id);
if (user == null) return NotFound();
user.Name = dto.Name;
await _db.SaveChangesAsync();
return NoContent();
}
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
{
var user = await _db.Users.FindAsync(id);
if (user == null) return NotFound();
_db.Users.Remove(user);
await _db.SaveChangesAsync();
return NoContent();
}
}
// ── Minimal API (.NET 6+) ──
var app = builder.Build();
app.MapGet("/api/users", async (AppDbContext db) =>
await db.Users.ToListAsync());
app.MapGet("/api/users/{id}", async (int id, AppDbContext db) =>
await db.Users.FindAsync(id) is User u ? Results.Ok(u) : Results.NotFound());
app.MapPost("/api/users", async (CreateUserDto dto, AppDbContext db) =>
{
var user = new User { Name = dto.Name, Email = dto.Email };
db.Users.Add(user);
await db.SaveChangesAsync();
return Results.Created($"/api/users/{user.Id}", user);
});
app.Run();// ── DbContext ──
public class AppDbContext : DbContext
{
public DbSet<User> Users => Set<User>();
public DbSet<Order> Orders => Set<Order>();
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=app.db");
protected override void OnModelCreating(ModelBuilder mb)
{
mb.Entity<User>(e => {
e.HasKey(u => u.Id);
e.HasIndex(u => u.Email).IsUnique();
e.Property(u => u.Name).HasMaxLength(100).IsRequired();
e.HasMany(u => u.Orders).WithOne(o => o.User)
.HasForeignKey(o => o.UserId);
});
}
}
// ── LINQ Queries ──
var activeUsers = await _db.Users
.Where(u => u.Active)
.OrderBy(u => u.Name)
.ToListAsync();
var usersWithOrders = await _db.Users
.Include(u => u.Orders)
.Where(u => u.Orders.Any())
.ToListAsync();
// ── Raw SQL ──
var users = await _db.Users
.FromSqlRaw("SELECT * FROM Users WHERE Active = 1")
.ToListAsync();
// ── Transactions ──
using var tx = await _db.Database.BeginTransactionAsync();
try {
_db.Users.Add(newUser);
await _db.SaveChangesAsync();
await _db.Database.ExecuteSqlRawAsync("UPDATE Stats SET Count = Count + 1");
await tx.CommitAsync();
} catch { await tx.RollbackAsync(); }
// ── Migrations ──
// dotnet ef migrations add InitialCreate
// dotnet ef database update
// dotnet ef migrations remove// ── Service Registration ──
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddSingleton<ICacheService, RedisCacheService>();
builder.Services.AddTransient<IEmailService, SmtpEmailService>();
// ── Scoped: one instance per HTTP request
// Singleton: one instance for app lifetime
// Transient: new instance every time
// ── Constructor Injection ──
public class UserService : IUserService
{
private readonly AppDbContext _db;
private readonly ICacheService _cache;
public UserService(AppDbContext db, ICacheService cache)
{
_db = db;
_cache = cache;
}
}
// ── Interface ──
public interface IUserService
{
Task<User> GetByIdAsync(int id);
Task<List<User>> GetAllAsync();
}
// ── Method Injection ──
public class MyController : ControllerBase
{
[HttpGet]
public async Task<ActionResult> Get(
[FromServices] IUserService userService)
{
return Ok(await userService.GetAllAsync());
}
}