C# Programming Language Articles

C# is Microsoft’s modern, statically-typed language for .NET development. This collection explores C# features, language evolution, practical patterns, and techniques for writing clear, efficient code in the C# ecosystem.

Language Evolution and Features

C# has evolved significantly since its creation, adopting features from other languages and innovating independently. Modern C# (10+) includes records for immutable types, nullable reference types for null-safety, pattern matching for elegant code flow, and async/await for asynchronous programming.

Records provide concise syntax for immutable data types with structural equality, ideal for domain models and data transfer objects.

Nullable Reference Types make null-safety explicit at compile time, preventing the infamous “billion-dollar mistake” of null reference exceptions.

Pattern Matching enables elegant code for type checking, null checking, and property matching without verbose if-else chains.

Async/Await abstracts the complexity of asynchronous programming, enabling responsive applications without callback hell.

Practical C# Development

Articles in this section cover language features, effective C# patterns, performance optimization, LINQ mastery, and integration with .NET libraries. Topics include null handling strategies, immutability patterns, error handling approaches, and leveraging type system features.

The goal is writing C# code that’s not just correct but also expressive, maintainable, and performant—code that communicates intent clearly and resists bugs through type safety and language features.

The Code You Write Today Is Tomorrow's Problem

The Code You Write Today Is Tomorrow's Problem

The code you create is a valuable legacy — my author bio. Not marketing copy. It’s the most expensive lesson from nearly two decades in production systems. This article explains what it actually means when you’ve lived with the consequences.
Stop Pretending TimeProvider Doesn't Exist

Stop Pretending TimeProvider Doesn't Exist

DateTime.UtcNow looks harmless. It is not. It is a hidden dependency you cannot control in tests, cannot reproduce in staging, and cannot freeze to catch the bugs that only surface at midnight or on the last day of the month. .NET 8 shipped TimeProvider to fix this. Two years on, most codebases still ignore it. Some planned to adopt it later. Later has not arrived.
Source Generators: The Build Performance Killer

Source Generator Costs

Source generators are powerful. They are also running on every single build, blocking IntelliSense, breaking Hot Reload, and multiplying their cost across every target framework you support. Nobody mentions this in the getting started guides. Here is how to measure the damage, find the culprits, and decide when source generators are actually worth it.
"We Store Secrets in appsettings.json": A Horror Story in Five Acts

"We Store Secrets in appsettings.json": A Horror Story in Five Acts

Every Azure subscription I’ve worked with has the same problem: connection strings with embedded credentials in appsettings.json, Service Principal secrets checked into Git history, storage account keys hardcoded everywhere. The credential sprawl is real. These aren’t careless developers. These are smart people applying on-premises patterns where they don’t belong. Azure Managed Identity flips the model entirely. Instead of your application proving identity by presenting a secret, Azure proves identity on your application’s behalf through cryptographic attestation. No secrets in code. No credentials in configuration. No rotation ceremonies. The Azure SDK’s DefaultAzureCredential handles authentication automatically, working identically in local development and production. Combined with RBAC, you scope permissions to exactly what each application needs. Not Contributor-level access to the entire subscription. Just the specific operations on specific resources that the application actually requires. This article walks through credential anti-patterns I encounter constantly, then shows the correct implementation using Bicep and .NET’s DefaultAzureCredential. The migration path is pragmatic: within weeks, not months, you can have zero static credentials in your codebase.
Real Professional Software Engineering in the AI Era

Real Professional Software Engineering in the AI Era

Throughout this series, we’ve established that AI-generated code without understanding creates productivity illusions that collapse in production (Part 1), and that the feedback loop between code and reality—compilation, testing, profiling, production—sharpens thinking in ways AI can’t replicate (Part 2). Now we confront the practical question: What defines professional software engineering when code generation becomes trivial? This final part examines the irreplaceable skillset: understanding execution characteristics (recognizing allocation patterns that cause GC pressure before deployment), asking questions AI can’t formulate (What’s the failure mode when this service is unavailable?), recognizing when plausible AI solutions diverge from correct ones, debugging production failures AI has no execution model to reason about, and evaluating maintainability for code that becomes tomorrow’s burden. We explore why prompt engineering optimizes for speed while architecture optimizes for survival, why “AI productivity” often means faster technical debt accumulation, and why the economic reality favors organizations that measure system reliability over lines of code generated. The feedback loop can’t be automated because closing it requires learning from production failures and applying that knowledge to prevent future ones—the irreplaceable discipline that defines real professionals in 2026 and beyond.