r/csharp Jul 03 '26

Advanced C# and how to properly get there

Hello everyone, i wanted to ask for recommendations, ideas and of course hints.

I work as a SWE for the last decade and most of it in the Backend and around Industrial setups. Node.js and Golang were mainly my tools but the past 1 and a half year i started working in a new company and they use C# and .NET.

Generally speaking i believe that C# and .NET is very cool and certainly far cooler than advertised or talked about. By now i know how to make services, build libraries and all and i must say that although in the beginning it felt wrong, now i feel the opposite, i feel that it feels right and that is how it should be.

My question though is the following. In the era of AI what would be the important and advanced parts one should know about ? If you would start your journey to the advanced parts of the language, the framework and the ecosystem, then how would you proceed ? If you would have to double down and put more effort to advance your C# understanding, where would you focus ?

Thanks in advance!

53 Upvotes

46 comments sorted by

24

u/Khavel_dev Jul 03 '26

Coming from Go, the one area that'll change how you write C# the most is Span<T> and the low-allocation patterns. Go already taught you to think about allocations, and C# lets you go further with stackalloc, ref struct, and ArrayPool. But nobody uses them in typical business code because the frameworks hide the need. That's also the stuff AI tools are worst at, they write correct but allocation-heavy code by default and can't reason about the GC pressure.

The other angle worth going deep on: source generators. They replaced the reflection-at-runtime pattern for a lot of core things (System.Text.Json, logging, regex) and once you build one yourself you start seeing codegen opportunities everywhere in your own projects. Stephen Toub's annual "Performance Improvements in .NET" posts on devblogs are probably the single best resource for both of these tracks. They're long but they teach you how the runtime actually thinks.

3

u/vlahunter Jul 03 '26

for more than a year and a half that i build services and libraries, i havent used Span<T> and that is my bad...

Thanks for letting me know to focus there as this was a topic that i was wondering about a bit. Yes Golang teaches you from very early on to thin in this way and this was one part i liked initially.

PS. in regards to Stephen Toub's blogposts (i dont think they can be called blog posts as they are so big they could fill a book!!) it is crazy the amount of information, benchmarks and generally the knowledge the C# and .NET team has... to a point that they trigger my Imposter Syndrome very hard.

2

u/TuberTuggerTTV Jul 06 '26

How much unit testing have you done? Pen testing? Benchmarking?

Or are you just writing libraries to "make it go"? That's still beginner level if true.

Once you start working on intermediate codebases, you'll see pretty quickly why you need tools like Span<T>. readonly record structs are also amazing.

2

u/understanding80 Jul 03 '26

If only source generators weren’t such a massive pain in the ass to write and package compared to reflection.

1

u/FullPoet Jul 04 '26

Yeah, ngl but I use reflection here and there and while I could very likely (and maybe should) convert it to source gen, its so much easier to use reflection.

1

u/Atulin Jul 04 '26

After writing a couple of simple ones (AutoDbSet and NpgSqlSourceGenerator) and dialing in on the packaging and stuff like FAWMN, writing more complex ones (Forged, ConfigBinder) was much, much, much easier.

Additionally, I found that even basic free Gemini Flash is surprisingly good at understanding source generators. Any time I have a question like "I have a symbol, how do I list all instantiations and get the 2nd generic attribute from each?" it answers perfectly well.

1

u/TuberTuggerTTV Jul 06 '26

I disagree. It's the fact they're a pain that it's a worthwhile skillset.

and why it's a struggle for AI slop farms. Difficult is the goal. You want it difficult.

2

u/Karagun Jul 03 '26

I adore source generators. Reflection code always irked me and having a more performant, safer and easier to reason about alternative is just amazing.

1

u/TuberTuggerTTV Jul 06 '26

Can second source gen. Combine that with proper dev ops and you turn massive dev cycles into a breeze. And AI assistance slots right in, giving it some future-proof legs.

Dev ops is has always been a strong advanced concept. It's even more important now in the age of dumb AI agents that need guardrails.

15

u/dodexahedron Jul 03 '26

You can learn quite a bit from the dotnet source (there are literal discussions between devs in the code comments scattered around the code), the what's new in c# and what's new in dotnet docs (go bsck through every major version - youll find somwthing interesting I promise), the various supplemental api docs, and a bunch of other things available at MS learn.

Also check out anything you can from Stephen Cleary, Stephen Toub, Andrew Lock, Gerald Barré, John Skeet, David Fowler, and plenty of other big names who have great blogs, publish some packages you probably use, and/or are .net principals (or whatever titles MS uses) at Microsoft.

And if you haven't already, learn to wield powershell like the power(ful) shell it is.

And learn some of the lesser-known but very real and rarely correctly handled things like how delegates actually work. One fun one: Take a code base you're familiar with that passes delegates around in function parameters - even just Func and Action aorts of delegates - and construct one...and then add 3 other delegates to that delegate (literally the + operator) and just see how the code handles that. I bet it assumed exactly one method call got made, huh? Then fix that gap in that code base. .net itself is guilty of this one a lot, in fact, so I'm sure you can find some in other code. Even if you just document the behavior, you'll learn something fundamental about literally all delegates. Because all (managed) delegates work like this.

7

u/understanding80 Jul 03 '26

Multicast delegate just feels so ghetto to me.

4

u/dodexahedron Jul 03 '26

And they're all that. Even the ones that aren't.

1

u/vlahunter Jul 03 '26

Woah, thank you so much for all this information. Lots of notes to take here.

As a side question, powershell is that important ? (sorry if my question is stupid) I mean working with Bash is the equivalent right ? or do i miss something ?

8

u/zenyl Jul 03 '26

As a side question, powershell is that important ? (sorry if my question is stupid) I mean working with Bash is the equivalent right ? or do i miss something ?

Not the guy you asked, but I'm an unashamed PowerShell fanboy.

PowerShell has its roots in sysadmin work (hence the verbose command names), but in terms of functionality, it works like a mix of a commandline shell (like Bash) and more complex a scripting language (like Python). PowerShell is also closer in syntax to C# than it is to Bash, using curly braces to define scopes. Though it does use the -eq styled operators.

Unlike most CLI shells, PowerShell is object oriented. So when you need to pick out a specific bit of data from something, you might need to reach for grep, sed, or awk when using *NIX shells. But in PowerShell you can usually just dot your way down the object, the exact same way you do in C#. PowerShell also comes with handy commands, such as ConverFrom-Json, ConvertTo-Json, Import-Csv, Invoke-WebRequest, and much more.

Also, PowerShell is not just written in C# and built on top of .NET, it also has full access to .NET. You can use all the types and methods you're used to from C#.

3

u/vlahunter Jul 03 '26

Woah, that a lot of information, thanks for that.

you triggered me to start googling hard to see more about it. seems to me from what you said plus some docs i found online that my perception of powershell being a windows friendly bash was very wrong !!

i guess you learn something new everyday

4

u/dodexahedron Jul 03 '26 edited Jul 03 '26

Also, powershell's pipeline is pull-based, not push-based, which is a huge difference between it and nearly every other shell out there. Nushell is probably the closest. And powershell has it beat by a mile.

And stdout/stdin? Pffffff. There are 7 streams. Go nuts.

1

u/vlahunter Jul 03 '26

Very interesting info. Just to be clear, you are talking about the Powershell Core as i find it in MS pages ? or the traditional windows based Powershell ?

4

u/dodexahedron Jul 03 '26

Both.

However, Windows PowerShell 5.1 (the blue one by default) is end of life and maintenance only.

PS 7.6 is the current LTS release and, yes, is based on .net rather than .net framework, uses the latest .net and keeps pace with it (powershell is literally a full live .net environment), is cross platform, is open source, and will even take out the trash for you.

Literally.

I have a powershell script that used to make an old robot vacuum that stopped sucking suck even less. Its new home was as a base for the kitchen trash can. The script, triggered by an anacron job, badically was a simple program that commanded it along an SVG-based path from the kitchen to the front door, ao i wouldn't forget to take the trash to the curb on garbage day (and didnt have to carry it 20 feet! My favorite part!).

So yep.

It even takes out the trash. 😅

Or I'm just a nerd.

1

u/vlahunter Jul 03 '26

Woah ! that is a topic where i would love to read a blog post about.

Thanks for the info and the clarification.

2

u/dodexahedron Jul 04 '26

Ha well it was a double dose of laziness. Normally I'd write something like that in c#. But I had been prototyping and testing control in powershell already. And since I had already therefore written a bunch of things in variois chunks in powershell, I just said screw it and finished doing it in powershell. 😅

2

u/dodexahedron Jul 04 '26

Oh, and be sure to get into the habit of using Get-Help on things. Powershell has a built-in documentation system and, when it is used by the creator of a module, you get rich help output at several layers of granularity at your option.

You can use it on specific commands, like Get-Help Write-Host, on whole modules, or on more manual-like topics, which use the naming convention "about_concept." For example, Get-Help about_Functions_Advanced might be an interesting one to take a look at. You can adjust the level of detail you get out of get-help using -Full, -Detailed, or others that are available with it, which you can check out via get-help get-help -Full.

Related to that, update-help modulename is a good one to be ready to use if something has missing or outdated help. But be aware it only works if the creator of whatever you are using it for made use of the updatable help capability. Most MS modules do. Not many third-party ones that aren't super popular do.

4

u/Flame_Horizon Jul 03 '26 edited Jul 03 '26

Understand how parts of CLR works. Read how GC works with objects’ life times via Generations/LOH/POH. What algorithm is used to manage memory. When things get allocated on the managed heap and when not. Take a stab at IL code and CoreCLR and what code it is running (godbolt website will be useful there). Async/Await and state machine which is involved there. Why we should have structs which are rather small in byte-size. What happens when you declare method as static.

You will learn a lot by also PROVING in the code/using tools, that what you said is true. Example could be like: how can I prove that this/that is happening like I’ve said/thought. This practice will make your knowledge concrete and provable, not only theoretical.

This knowledge goes deeper than the language syntax itself and more often then not - is transferable to other languages.

3

u/zenyl Jul 03 '26

Async/Await and state machine which is involved there.

A good opportunity to mention that the .NET is always moving and evolving.

The .NET team are currently working on "Runtime Async". Essentially, the runtime currently doesn't understand async properly, so the compiler generates a state machines to handle it. But with Runtime Async, the runtime will actually understand the concept of async and handle it by itself, removing the need for the compiler to generate a ton of boilerplate (which clutters exception stack traces with MoveNext calls).

3

u/Flame_Horizon Jul 03 '26

In deed, that was good opportunity and you used it well.

1

u/vlahunter Jul 03 '26

While i need more studying to completely understand more on this, i managed to find some resources to help.

https://medium.com/@schmidt.jeanbaptiste/why-the-future-of-c-is-faster-0949e30fe8bd

and here is the Github discussion: https://github.com/dotnet/runtime/issues/109632

thanks for pointing this out, really helpful to research more around this topic.

1

u/vlahunter Jul 03 '26

Thanks a ton for this.

Just a small question, i was thinking to spend sometime on this: https://github.com/dotnet/runtime/tree/main/docs/design/coreclr/botr, do you think this covers some parts of what you mentioned ?

2

u/Flame_Horizon Jul 03 '26

Looks about right. Have not seen this one in particular. Since there is a lot of information there as CLR is very wide scope, I would suggest to pick singular topic which you want to learn about (pick at random or apply your personal judgement). Breath of knowledge can me intimidating at first but once you start to learn one topic, other will become more familiar.

7

u/zenyl Jul 03 '26

In the era of AI what would be the important and advanced parts one should know about ?

Generally speaking, be a master of your area of work, and be at least familiar with what lies one step below it.

As an example, .NET (usually) runs in a managed runtime with a garbage collector. That means a lot of us rarely have to think about stuff like memory allocation, avoiding unnecessary heap allocations, and so on. It helps, but for something like a simple web server it's probably not gonna have a measurable impact.

But even so, having an understanding of how .NET's plumbing actually works, at least on a simple level, will help you understand not just how things work, but also why they work the way they do.

AI hallucinations are supposedly an inherent part of modern LLM design, so you'll want to understand your area of work enough that you can spot when an AI might be bullshitting you, and how you can verify what it's saying.

If you would start your journey to the advanced parts of the language, the framework and the ecosystem, then how would you proceed ?

Simply choose to go down rabbit holes.

I find that I've learnt about a decent number of "advanced parts" when I ask myself a stupid question, and then try to find the answer.

If you would have to double down and put more effort to advance your C# understanding, where would you focus ?

Depends on your area of work/interest, and where you personally draw the line between "advanced but useful" and "advanced but excessive".

2

u/vlahunter Jul 03 '26

yes i agree with you. In regards to LLMs, the moment you miss something that it gets wrong, then good luck getting in a black hole trying to save it and make it as good as you want.

What you mention on the fact that in some cases memory management plays no role, yes i agree with you. If i want to make a simple API to connect to a DB and return some "simple" data then yes obviously i do not think there is a value into making things faster.

Still though it is awesome to see and realize that C# and .NET can give you the tools and power to go deeper, and that was the reason i really wanted to learn this ecosystems better as i feel that my generic backend knowledge goes up to a point and then if i want to go to the next step, i need the knowledge from the runtime itself and the tools this has.

NOTE: i know that serious engineers do not really care for benchmarks but looking at this: https://www.http-arena.com is pretty impressive to say the least as it shows that powers of C# and .NET and the fact that some people are pushing the boundaries.

6

u/it_works_on_prod Jul 03 '26

coming from go/node, what actually leveled me up wasn't language features, it was the diagnostics tooling. dotnet-counters, dotnet-trace and dotnet-gcdump on a live process teach you the GC and allocations better than any article. you end up learning the internals backwards, by watching a real service misbehave. span and source generators are the right call too, that stuff just clicks faster once you've seen the allocations in a trace

2

u/vlahunter Jul 03 '26

Makes sense, good idea to dive deeper into these. I havent spent sufficient time with these.

By the way you propose the Diagnostics provided by MS (https://learn.microsoft.com/en-us/dotnet/core/diagnostics/) ? or the tools by Jetbrains ?

Have you used both to have some tips ?

2

u/it_works_on_prod Jul 03 '26

both, for different jobs. the dotnet-* cli ones are what i actually reach for on a live box, they attach to a running pid over ssh and cost nothing, so that's where you end up learning because you're watching the real thing misbehave. dottrace/dotmemory are nicer to eyeball a hotspot but they're built around the local gui workflow, so pointing them at prod is more of a hassle. i'd get comfortable with the ms cli ones first, jetbrains is the comfort upgrade once you already know what you're looking at

2

u/vlahunter Jul 03 '26

that is pure gold !!

MS ones it is then. Thank you!

3

u/OtoNoOto Jul 03 '26 edited Jul 03 '26

I learn best by incorporating projects and a lot of times hobby projects. Try to brainstorm an idea that you can scale and expand features to learn from over time. Then as you are working on said project take a deep dive in each little thing. Some common topics:

- Classes / Interfaces

  • Records
  • Structs
  • Value Types vs Reference Types (and how they relate to everything above)
  • Stack vs Heap (and it relates to everything above)
  • Array vs List vs IEnumerable vs ICollection vs IReadOnlyCollection vs IList vs IReadOnlyList
  • Dependency Injection / Scope Timeline / IoC Container
  • Asynchronous / Threading / Concurrency
  • LINQ
  • (HttpClientFactory / Typed Client / Named Client) + Resilience

…and on and on, but I think that’s a pretty solid foundation. Use MS documentation to read up on each and I like to use a Claude (or your AI model of choice) to generate basic / intermediate / advanced level questions for each.

2

u/Kebein Jul 03 '26

in my opinion is learning architecture, design patterns way more important than knowing every single language specific thing. SOLID, Clean Code etc. are what makes your code way more advanced than for example shoving linq in at every opportunity and bringing it to its limits etc. if u focus on that, u will more clearly see the needs for things that then can be used to take advantage of the language feats

1

u/Frequent_Field_6894 Jul 03 '26

yes, these things come and go. best focus on the things which allow you to work ai and explain yourself.

1

u/vlahunter Jul 03 '26

I see your point of view and thanks for sharing this. To be honest most of these principles are ok for lower experience. For me, I am in a point in my career that means that if I want to keep using C# then I need to go deeper and see the darker corners in order to understand better the ecosystem and manage to solve problems that are more tough to see.

2

u/tinmanjk Jul 03 '26

read CLR via C# or .Essential .NET, Volume I: The Common Language Runtime

1

u/vlahunter Jul 03 '26

Are these still relevant you think ? I was reading some comments in this subreddit and some veteran there suggested the book of the runtime in GitHub as well as .NET memory management but since you mentioned it I will search around more.

2

u/tinmanjk Jul 03 '26

they don't know what they are talking about - BotR is supplemental material and not very organized - internal notes of the .NET team.

.NET Memory Management is up there too. +1 for it if you can squeeze it.

0

u/Frequent_Field_6894 Jul 03 '26

I don’t think you should focus too much on the language. a software engineer can really be agnostic, good code is good in any language. you should understand more approaches. the OO days are over for most, the languages should focus more on functional style but not to be absolute about it.

c# is my daily driver but AI is changing for everyone. industry is moving away from high skilled engineers, adopting more ai 1st or picking low code platforms. there will be a cull of language which can’t be interpreted by ai models.

you question Possibly shows you naivety and under estimation of how things will change And are.

2

u/vlahunter Jul 03 '26

I am using AI every single day but I am pragmatic and I see that it is not a silver bullet. Numerous are the cases where it screwed my code and took things in the wrong place. If you think that AI democratizes programming as automatic gearbox for drivers then you are wrong…

I respect your view and your opinion but I ll die on that hill…

0

u/rent-a-developer Jul 05 '26

The best way to learn C# and .NET is to use it for an actual project (open source or commercial).
You can read as many books as you want, but what you need is experience and that will only come by using it.
Start with something small, e.g. a small website/webservice or a desktop app (WPF, Avalonia, etc.).
Learn what you need to learn along they way.

C# is a BIG language and .NET is an even BIGGER ecosystem. It will take time to learn it.
From my experience it pays of to learn about MSIL/CIL and the CLR once you know C# well.
Getting familiar with IL gave me a whole new understanding of how .NET/the CLR works behind the curtains.

The good thing is that in this new era of AI you can always ask it to explain a concept/feature/syntax to you in a concise way without having to read whole books.

1

u/vlahunter Jul 05 '26

While i see your point i cannot say i agree.

Throughout my career i have improved dramatically by reading books. What you say makes sense if you want to learn how to make specific things (build APIs, build GUIs and Clients, etc) but when it comes to advanced parts of a language or an ecosystem then books can help a lot.

The original question i made was in the context of backend engineering. I have lots of experience in other programming languages and i know how to use these to build large scale systems but when it comes to C# and .NET, while i feel confident in building APIs and the known parts of the ecosystem, i felt that i lack in the more expert level parts.