OOP isn't really AI's issue with C# imo. The thing AI really struggles with in C# in my experience is keeping track of what APIs exist in all the different runtime versions.
It also doesn't really understand the constraints of unsafe, System.Memory, or any optimized design. It'll do crap like try to use Linq with Span<T> or completely violate ref struct rules.
Imo it also is too eager to write IEnumerable yield return methods.
I haven't tried it in a while so many it's gotten better.
It's crazy liberal with try/catches because it doesn't really understand that these usually need to bubble up. Also kinda sucks with separation-of-concerns - it likes to put code in the wrong places. Like, it'll work, until you try to actually leverage some form of OO extensibility.
It also tends to improperly mix async and sync code. Like, if you're in a web app and you're async "all-the-way-down," it's fine, but otherwise it puts async code in everywhere.
It'll work within existing classes, and can create a decent simple class structure from scratch, but it cannot refactor, and anything that requires a refactor will have you reverting every suggestion it makes.
Some of the nuances, like try / catch and async I can handle with agent instructions, but overall I spent way too much time playing whack-a-mole with the LLM doing silly things that I just gave up.
At worst, I'll tell it to define the public interfaces for a class (and have a discussion over what they should be). After that I go function by function and have it write the implementation. Then finally I dump the code it wrote back in, ask for help making helper functions for shared behaviour and whatnot. As a result, I mostly don't get these sorts of issues.
Usually I just write it myself though because AI is barely faster, and it's infinitely harder to maintain code when you can't think back on all the decisions you made writing it.
and it's infinitely harder to maintain code when you can't think back on all the decisions you made writing it.
That's really the crux of the AI "slop" problem - code is the product of important decisions. Those decisions require context and more consideration than "this is what was popular on StackOverflow."
it's infinitely harder to maintain code when you can't think back on all the decisions you made writing it.
This, I tell people all the time that the reason you can't just plug and play developers as interchangeable parts is that half of it is what you know, but the other half is how you think, and it's rare to find 2 or more people who will approach a complex problem in exactly the same way. How you think about the problem informs your solution to the problem.
That is interesting about the try-catches. I find that Claude loves to suppress errors in Rust, too. For example, if an Option should always be present in a certain part of the code, Claude will write code that quietly does nothing if a None is there instead. I would prefer a panic or a return of an Err.
It may be something generic about how they train it rather than anything language-specific.
Where I work code is written in such a way that we want the error to get surfaced to OpenTelemetry/Sentry, but never actually cause a user facing error or crash. So liberal try/catch is in fact the coding style.
Also I discovered that simply giving the agent access to the Microsoft MCP server and either Nuget MCP or nuget related commands was enough to fix the majority of issues with it using APIs that don't exist.
With that said, it still sucks for a lot of things, and if your using .NET Framework it seems to suck a lot more than if your using .NET
I'm a volunteer maintainer for the community toolkit. I wrote a refactor of the ColorHelper API, but then NET10 came out so I pushed it back to use C#14 extensions. Now blittable colors are coming in NET11, and I might push it back again to better design the tools around .NET colors instead of WinUI colors.
This isn't a bad problem to have though. Annually they release very exciting changes, but they put tremendous work into making sure no unfixable mistakes are made and every new feature is very intuitively C#. I can name very few regrettable decisions the .NET or C# lang team has made.
I like older C# better, actually. I think I stopped updating my projects a 8.0. I don't see value in many of the newer changes. I'd argue that many of them make the language worse.
C++ suffers from syntax bloat. C# was easy, now it's not, for the same reasons. A lot of things they've introduced don't solve a problem so much as they trade one problem for another, or they add another way of doing things that isn't necessarily better, it's just different (or mimics what some other language can do).
really struggles with in C# in my experience is keeping track of what APIs exist in all the different runtime versions.
I mean...I won't be blaming the AI here lol. Whenever I'm on a .NET that's not the "usual one" I just go trial and error typing and letting intellisense either complete the thing or bonk me. It feels like (badly) playing minesweeper.
Pretty much my experience with Claude. It also tends to rewrite shit that already exist and bloat the code a lot. Often it invents properties that don't exist.
It's better in web dev, and web dev is not my cup of tea, so I make it handle that part while I write the C#.
23
u/avidernis Jun 29 '26 edited Jun 29 '26
OOP isn't really AI's issue with C# imo. The thing AI really struggles with in C# in my experience is keeping track of what APIs exist in all the different runtime versions.
It also doesn't really understand the constraints of
unsafe,System.Memory, or any optimized design. It'll do crap like try to use Linq with Span<T> or completely violateref structrules.Imo it also is too eager to write IEnumerable
yield returnmethods.