C#
Modern C# and .NET -- async/await, LINQ, records, nullable reference types, performance, and the enterprise ecosystem that dominates NZ government and corporate
C#
C# started life in 2000 as Microsoft's answer to Java -- a curly-brace, object-oriented language for the .NET runtime. Two decades later it is one of the most feature-rich mainstream languages in production, having absorbed functional programming ideas, value types, pattern matching, and a sophisticated nullable type system while staying broadly familiar. The language that ships today is barely recognizable from the one that shipped in 2005, and the pace of change is part of what makes it interesting.
The engineers who underestimate C# are usually picturing the verbose, enterprise-y Java clone it once was. The modern language -- with records, pattern matching, top-level statements, and async/await baked deep into the runtime -- is concise, fast, and genuinely pleasant. And since .NET Core, it runs natively on Linux and macOS, which removed the single biggest reason teams avoided it.
Philosophy: Pragmatic and Multi-Paradigm
C# does not have the focused, opinionated philosophy of Go or Rust. It is a kitchen-sink language that adds features aggressively, and the result is a tool that lets you write in whatever style fits the problem:
- Object-oriented by default. Classes, interfaces, inheritance, and encapsulation are the foundation. Most enterprise code is organized this way.
- Functional when it helps. LINQ, immutable records, pattern matching, and first-class delegates let you write declarative, expression-oriented code.
- Pragmatic over pure. C# rarely forces you into a paradigm. It gives you the tools and trusts you to choose. The downside is a large surface area; the upside is flexibility.
- Backward compatible, forward moving. New language versions add features without breaking old code. A C# 7 codebase compiles fine on C# 12, and you adopt new syntax incrementally.
.NET, Not Just C#
C# the language is only half the story. The other half is .NET -- the runtime (CLR), the just-in-time and ahead-of-time compilers, the garbage collector, and a vast first-party class library. When people say "C# is fast" they usually mean the .NET runtime is fast: a tiered JIT that re-optimizes hot paths, a generational GC, and increasingly an AOT path that produces native binaries with no runtime dependency at all.
The versioning matters in practice. .NET Framework (up to 4.8) is the Windows-only legacy platform that still runs a huge amount of NZ enterprise and government code. .NET (Core, then 5, 6, 7, 8, 9...) is the modern, cross-platform, open-source successor. Even-numbered releases are LTS (Long-Term Support, three years); odd-numbered are STS (Standard-Term, 18 months). For production, target the latest LTS unless you have a reason not to.
How This Section Is Organized
The C# articles go beyond "you can write it" toward "you understand it" -- the idioms, the sharp edges, and the runtime behavior that separates senior engineers from mid-level ones:
- Language Features -- records, pattern matching, nullable reference types, and the modern syntax (primary constructors, collection expressions,
requiredmembers, generic math) - Project & Solution Structure -- SDK-style
.csproj, project vs package references, solution layering,Directory.Build.props, and central package management - Async & Concurrency --
async/await, the pitfalls that deadlock production (ConfigureAwait, sync-over-async),ValueTask,IAsyncEnumerable, and channels - LINQ & EF Core -- LINQ as C#'s signature feature, the
IQueryableboundary, and Entity Framework Core in depth: change tracking, N+1, migrations, and when to reach for Dapper - ASP.NET Core -- dependency injection, minimal APIs, the middleware pipeline, configuration and the Options pattern, and background services
- Configuration & Secrets -- the layered configuration system, the Options pattern in depth, user secrets, environment variables, and Azure Key Vault
- Authentication & Authorization -- authentication schemes, JWT bearer and cookie auth, ASP.NET Core Identity, and the policy/requirement/handler authorization model
- gRPC -- contract-first services with protobuf, the four call types, interceptors, and where gRPC beats REST for service-to-service traffic
- Blazor -- full-stack C# on the front end, the Server vs WebAssembly hosting models, render modes, and component basics
- SignalR -- real-time web with hubs, transport fallback (WebSocket/SSE/long polling), groups and users, and scaling out with a Redis backplane
- Observability -- OpenTelemetry in .NET: distributed tracing with
ActivitySource, metrics withMeter, structured logging, and OTLP export - Messaging -- asynchronous messaging with MassTransit over RabbitMQ and Azure Service Bus: consumers, retries, sagas, and the transactional outbox
- Background Jobs -- in-process
BackgroundService, Hangfire for durable scheduled and recurring work, and choosing between jobs, queues, and Quartz - Caching --
IMemoryCache,IDistributedCache, Redis, and the .NET 9HybridCache, plus stampede protection and invalidation - Containerization -- Dockerizing .NET, multi-stage and SDK-published images, chiseled and distroless base images, and container-aware runtime tuning
- Performance & Memory --
Span<T>/Memory<T>, allocation-free code, the garbage collector, Native AOT, and source generators - Source Generators -- compile-time code generation with Roslyn: incremental generators, the
System.Text.Json/LoggerMessage/regex generators, and writing your own - Testing -- xUnit, parameterized tests, mocking with NSubstitute/Moq, and FluentAssertions
- Code Quality & Static Analysis -- Roslyn analyzers,
.editorconfigrule severities, warnings as errors, third-party analyzer packs, and NDepend for architecture governance - Migrating to Modern .NET -- moving off .NET Framework, the single most valuable C# skill in the NZ government and enterprise market
Ecosystem Essentials
The .NET ecosystem is mature and largely first-party, which means less dependency churn than the JavaScript world:
| Tool / Library | What It Does |
|---|---|
| ASP.NET Core | Web framework -- APIs, MVC, Razor, Blazor, SignalR |
| Entity Framework Core | ORM with LINQ-to-SQL and migrations |
| Dapper | Lightweight micro-ORM for raw SQL performance |
| xUnit / NUnit | Test frameworks |
| Serilog | Structured logging |
| MediatR | In-process messaging for CQRS-style architectures |
| Polly | Resilience -- retries, circuit breakers, timeouts |
| OpenTelemetry | Vendor-neutral tracing, metrics, and logging |
dotnet CLI | Build, test, publish, and manage packages |
C# in New Zealand
C# is one of the most in-demand languages in the NZ market, second only to JavaScript/TypeScript in volume. It dominates government and corporate IT: most public-sector systems, council infrastructure, and large enterprise back-ends run on .NET. Datacom -- one of NZ's largest IT services firms -- and the many government contractors that build for agencies like IRD, MSD, and ACC are heavy C# shops.
The work skews toward enterprise back-ends, line-of-business applications, and integration systems rather than greenfield startups, so the culture tends to value reliability, maintainability, and process over cutting-edge experimentation. If you want stable, well-paid engineering work in NZ -- particularly in Wellington's government sector -- strong C# and .NET skills open more doors than almost anything else. Pair it with cloud experience (Azure especially, given Microsoft's enterprise relationships) and you are highly employable.
A large share of that work is not greenfield at all -- it is modernizing .NET Framework systems onto modern .NET. The engineer who can lead that migration safely is worth more than the one who only writes new code, which is why it gets its own article.