C# and .NET Core: Cross-Platform Enterprise Development
Language Features and Type System
C# combines C++ performance with Java simplicity. Null-coalescing: string name = user?.Name ?? "Unknown" (returns name if user exists, else "Unknown"). Nullable reference types: #nullable enable (string? = nullable, string = non-null). Property auto-initialization: public string Name { get; set; } (compiler generates backing field). Expression-bodied members: public int Age => DateTime.Now.Year - BornYear; (concise syntax). Async/await: async Task FetchData() { var data = await httpClient.GetStringAsync(url); return data; } (readable async code). LINQ: Language Integrated Query. var adults = students.Where(s => s.Age >= 18).Select(s => new { s.Name, s.Age }).OrderBy(s => s.Name); (SQL-like syntax, type-safe). Query methods: Where, Select, GroupBy, Join, Union. Lazy evaluation: LINQ queries don't execute until enumerated (streaming). Extension methods: public static void LogInfo(this string msg) { Console.WriteLine($"[INFO] {msg}"); } enables "message".LogInfo(); (fluent API). Records (C# 9+): record User(string Name, int Age); (immutable by default, structural equality).
.NET Core Architecture and Runtime
.NET Core: cross-platform runtime (Windows, Linux, macOS). CLR (Common Language Runtime): manages memory, JIT compilation, garbage collection. JIT: compiles IL (Intermediate Language) to native code at runtime. First execution: warm up (~500ms), subsequent calls fast. Tiered JIT: initial execution uses quick compilation (optimized for speed), background thread recompiles hot code (optimized for throughput). Performance: similar to Java. Garbage collection: generational (Gen0 <1ms, Gen1/Gen2 slower). GC tuning: server GC (background collection), workstation GC (low-latency). Boxing: value types boxed to objects (performance cost, avoid in hot loops). AOT (Ahead-of-Time) compilation: .NET 7+ supports AOT (compile before deployment, no JIT). Benefit: instant startup (~10ms cold start vs 500ms JIT), no runtime dependencies (single .exe). Trade-off: larger binary (~30MB vs 5MB JIT), slightly slower than JIT (no runtime optimization). Self-contained deployments: single executable (includes runtime, no .NET installation needed).
ASP.NET Core and Web Framework
ASP.NET Core: high-performance web framework (50K+ requests/second per core). Startup: services.AddDbContext (dependency injection setup). Middleware pipeline: app.UseAuthentication() → UseAuthorization() → UseRouting() → endpoints MapGet/MapPost. Example: app.MapGet("/api/users/{id}", async (int id, UserService svc) => await svc.GetUser(id)) (endpoint with DI). Startup time: ~100-500ms (slower than Go/Node, faster than Java). JSON serialization: System.Text.Json (built-in, no external dependency, ~50% faster than Newtonsoft). Entity Framework Core: ORM for database access. DbSet queries: context.Users.Where(u => u.Active).ToList(). Change tracking: modifications detected automatically (SaveChanges updates database). Relationships: navigational properties (user.Posts loads posts). Migrations: ef migrations add AddUserTable (creates migration script), ef database update (applies to database). Health checks: app.MapHealthChecks("/health") (Kubernetes liveness probes). Logging: ILogger injected automatically (structured logging compatible with Serilog).
Dependency Injection and Configuration
DI container: built-in (no external library needed). Register services: services.AddSingleton, AddTransient, AddScoped. Singleton: single instance lifetime (shared across all requests). Transient: new instance per request (stateless). Scoped: one instance per HTTP request (database contexts). Inject: public class UserController(UserService service) { ... } (constructor injection, C# 11+ primary constructor). Interface-based DI: services.AddScoped() (implementation can be swapped). Configuration: appsettings.json + environment variables. Example: { "Database": { "ConnectionString": "..." } } accessed via IConfiguration.GetConnectionString("Database"). Secrets: user-secrets init (development only, safe from source control). Options pattern: IOptions injected, strongly-typed configuration. Factory pattern: AddScoped(sp => new T(sp.GetService(), sp.GetService())) (custom instantiation).
Testing and Dependency Mocking
Unit testing: xUnit framework (MSTest, NUnit alternatives). Example: [Fact] public void UserName_IsCorrect() { var user = new User { Name = "John" }; Assert.Equal("John", user.Name); }. Parametrized tests: [Theory], [InlineData("John", 30)], [InlineData("Jane", 25)] runs test multiple times. Mocking: Moq library. var mock = new Mock(); mock.Setup(s => s.GetUser(It.IsAny())).ReturnsAsync(new User { Name = "John" }); (setup mock behavior). AutoFixture: generates test data automatically. Integration tests: TestWebApplicationFactory bootstraps real app. var client = factory.CreateClient(); var response = await client.GetAsync("/api/users") (real HTTP calls, but in-memory). Snapshot testing: capture output, compare future runs (detect regressions). Code coverage: coverlet measures test coverage (target 80%+). Profiling: Benchmark.NET measures performance. [Benchmark] public void StringConcat() { ... } runs many iterations, reports statistics.
Azure Integration and Cloud Features
Azure SDK: client libraries for Azure services. Azure Storage: BlobClient uploads/downloads files. TableClient stores structured data (NoSQL). Queue: ServiceBusClient for message queues. Cosmos DB: globally distributed database. Querying: container.GetItemQueryIterator("SELECT * FROM c") (SQL-like syntax). Scaling: automatic partitioning (horizontal scaling). Azure Functions: serverless. [FunctionName("ProcessFile")] runs on trigger (blob, queue, HTTP). Language: C#, supports async/await naturally. Azure Kubernetes Service: orchestrates containerized .NET apps. Application Insights: monitoring and diagnostics. Auto-tracks requests, exceptions, performance metrics. Custom events: telemetryClient.TrackEvent("UserLogin", properties). Alerts: trigger on error rate, latency thresholds. DevOps: Azure Pipelines (CI/CD). YAML pipeline automates build → test → deploy.
Performance Optimization and Best Practices
Memory pooling: ArrayPool.Shared.Rent (reuse arrays, reduce GC pressure). Span: zero-allocation slices. Stackalloc: allocate on stack (very fast). Example: Span buffer = stackalloc int[256]; (no heap allocation). Struct vs class: value types (struct) faster for small objects (no heap allocation), but copied on assignment. Use struct for small (<100 bytes), immutable data (points, colors). Inlining hints: [MethodImpl(MethodImplOptions.AggressiveInlining)] for hot methods. SIMD: System.Numerics.Vectors (vector operations for ML). Async patterns: avoid blocking (Task.Result causes deadlock in some contexts). Correct: await task. StringInterpolation: $"{name}" (more efficient than string.Format). Caching: IMemoryCache (in-process), StackExchange.Redis (distributed). Compression: GzipStream reduces response size (30-80%). Security: HTTPS enforced, HTTPS redirect middleware, HSTS headers, CORS policy configured.