C# 13: Yes, I Know It Dropped Last November. No, I Didn't Have Time

C# 13 has been out for a while, but if you're like me — juggling legacy code, corporate chaos, and a home server that died a dumb death — you might be catching up late. Here’s what actually matters in the new release: shouting at nulls, prettier collections, and lambdas that finally get it together.

C# 13: Yes, I Know It Dropped Last November. No, I Didn't Have Time
C# 13 introduces a lot of genuinely useful features

Look, I know I'm late to the party. C# 13 came out last November and the internet exploded with Medium posts, YouTube thumbnails screaming "THIS CHANGES EVERYTHING!!", and developers tweeting syntax like it was SwiftUI all over again.

Meanwhile, I was wrestling with legacy .NET Framework code, my home server suffered a heroic but entirely preventable death (RIP, poor little RAIDless warrior), and the day job kept tossing urgent-but-not-important fires onto my desk. So no, I didn’t get to dive into the newest C# release the second it landed. But I’m here now. I’ve brewed coffee, done the reading, and kicked the tires.

Here’s what you actually need to know about C# 13 — from the perspective of someone who writes production code, not demos.


1. Parameter Null-Checking: void Foo(string bar!!)

This one’s a treat. C# 13 lets you declare your intent right in the method signature with !! — and yes, it looks like it’s shouting at you.

void Foo(string bar!!)

It means “this better not be null or we’re throwing hands.”

No more boilerplate like:

if (bar == null) throw new ArgumentNullException(nameof(bar));

It’s like writing:

“Hey, can you come here and bring me the screwdriver?”
[You show up empty-handed.]
“THE SCREWDRIVER!!”

It’s loud. It’s clear. It’s the method signature equivalent of an assertive slap on the wrist. And honestly? I love it.

It’s also compile-time enforced, so if you try to pass in null, the compiler throws a fit before runtime. Clean, declarative, and exactly the kind of feature you’d expect a modern language to have years ago.

Caveats?

  • Works for reference types, not value types (because int can’t be null, obviously).
  • It’s not a substitute for more nuanced validation — just a cleaner way to enforce “don’t hand me trash.”

But for 90% of your methods? It’s the perfect way to say “I meant what I said.”


2. Collection Expressions: [1, 2, 3] and Friends

Look, I’m not saying array initializers were bad. I’m just saying this:

var nums = [1, 2, 3];

is cleaner, shorter, and aligns with modern syntax trends (and possibly with your ADHD-fueled desire to type less boilerplate). The compiler turns this into an array, a List<T>, or your own collection type if it supports Add() and an initializer. Very flexible. Very nice.

Bonus: collection expressions work great in pattern matching too. More on that below.


3. Lambda Overload Resolution: It's No Longer a Horror Movie

Let's say your code had something like this:

void DoSomething(Func<int, string> a) { ... }
void DoSomething(Func<double, string> b) { ... }

Before C# 13, this was a toss-up:

var x = 6;
DoSomething(x => x.ToString()); // Which overload does this match???

You would get an error about the call being ambiguous.

Now, lambdas can match overloads better, especially when multiple method signatures are in play. The compiler does a better job inferring intent.

Do you still have to be careful? Yes. Can you now write cleaner, more readable delegate code? Also yes. It's still not perfect, but it's much smarter.


4. Ref + Params = Chaos Now Allowed

This used to be banned:

void DoThings(params ref int[] numbers)

But C# 13 said “let the chaos reign.” You can now use ref and params together. Why would you do this? Edge cases. Interop. Hardcore perf scenarios. Debugging the cursed spawn of a C++/CLI binding.

Most of us will never need this. But it’s a power tool — and it’s nice to know you can if you must.


5. More Pattern Matching Magic

Pattern matching gets more expressive every release, and C# 13 keeps the trend going.

if (value is [1, 2, 3]) { ... }

Yes, you can match whole collections now. Nest them. Mix them. Turn your if-statements into modern art. It’s a joy for people who’ve been waiting for the language to catch up with their brain’s need for concise, expressive branching logic.

Also: property patterns got a polish. Deconstruction patterns got a buff. It's small stuff, but it's cumulative.


TL;DR – What You Should Actually Care About

  • Use !! for parameters. It’s clean, defensive, and readable.
  • Try [1,2,3] instead of verbose initializers. Feels good.
  • Be aware of better lambda overloads — especially in LINQ-heavy code.
  • Ref/params is niche, but cool if you’re a masochist.
  • Pattern matching is basically a mini-language now. Use it.

Final Thoughts

C# 13 is a quieter release than some of its predecessors, but it’s refined. It sharpens the edges you actually touch day to day. These aren’t novelty features — they’re time savers. Clarity boosters. And in the case of parameter null-checks, potential bug squashers.

Now, go forth. Add some !!, refactor some arrays, and if you find yourself reaching for params ref — I salute you, you glorious chaos gremlin.

Stay sharp.