Follow @davidfowl on Twitter/Github and look at "Minimal API" code for beautiful C# code and examples for specific scenarios.
C# is VERY different from even just what things were 2 years ago. You can now build a full-on app with the same number of lines that a Node/Express/Flask app. Except the .NET runtime is about 5-10x faster than those runtimes.
That looks very TypeScript/NodeJS-esque. I am not very familier with the .NET ech system. How do you write tests for some of these API examples? E.g. in the NodeJS eco-system we have e.g. Jest with Superserver and Nock (for mocking/intercepting outgoing requests). What does a typical test suite in a .NET core project look like?
I'm surprised we don't see a bigger uptick in C# usage given the growth of TypeScript and how similar the two languages are. If you know C#, it's pretty easy to pick up TypeScript and vice versa.
A programming lanaguage is only a relatively small aspect of making software. The eco-system is far more important, i.e. frameworks, libraries, tooling, etc. Personally, the majority of my day-today work is TypeScript/NodeJS and the reason I don't use C# is that I just don't want to be stuck in Microsofts eco-system.
As someone who has only built Node/TypeScript or .NET APIs for the past few years, I can say that the ecosystem of .NET is dramatically better than Node. Everything works and there's a high quality library for everything.
The only thing I miss is the phenomenal structural typing of TypeScript. That by itself is enough to tempt me to use Node sometimes.
So I guess I disagree with everything you said, in the end :)
Thanks for the repo! I love to compare programming languages side by side as you did. For example, a few months ago I was learning about Java streams, but they looked a bit convoluted to me, especially the collectors. Then, I reviewed the same concept in Elixir and then it was clear to me why the collectors are needed.
TS is great for the front-end where JS is inevitable, but I find not a great choice for backend work.
Node runtime is overall more prone to security threats (prototype pollution attacks, rogue packages, etc.). See GitHub's 2020 State of the Octoverse report for details [0]. With the Node ecosytem, there is a very large dependency tree that creates a large surface area for security risks. Then you may be dependent on the community to find and and patch. With dotnet, at least Microsoft has professional, paid engineers maintaining a broad set of base class and first party libraries which provides a LOT more functionality out-of-the-box.
For some workloads, having the higher throughput of dotnet is also a boon.
>Except the .NET runtime is about 5-10x faster than those runtimes.
I'm as guilty as anyone for using anecdotal evidence but any reliable numbers that prove this? Stats I recall from years ago showed V8 destroying the .NET CLR.
One JS framework smokes, but most of the C# ones are above the JS ones. I don't know what's that "just-js" thing at the top though, I suspect it's not really a framework.
I am a .NET dev not been keeping up admittedly but was blown away by the Blazor docs and what that can now do. HN comments are what made me look. Last time I looked it was a POC. I didn’t realize it had become a thing! It might convince me not to bother learning Phoenix.
5-10x faster usually also means that it makes far more efficient use of resources, so if you’re running something in the cloud, you can achieve the same throughput at a lower cost and are more resistant to spikes.
A tip for going over github code is to use the github.dev domain. This will help going over the code in an IDE (if you'd like that), that provides you language features, and easier navigation (eg Go To/ Peek Definitions, or References). It also helps avoid to clone a large repo to do the same locally.
"DotNEXT" is a repo that enhances the code from .NET core, and has examples of using new API's that you can't even find tutorials for on the internet/examples from in public code.
For instance, there's been a class since .NET 6, "RandomAccess", for high-performance random-access file I/O (potentially async), and I couldn't find a single damn use of it on the internet.
But then this repo had a whole utility class for it, and it's chock full of similar things:
Similarly, I would recommend stuff by the .NET core team.
I'm particular biased towards the low-level/interop team. Anything by Tanner Gooding is great, stuff by Michal Strehovský, Aaron Robinson, Elinor Fung.
ReferenceSource is the code from the Windows framework and I'm pretty sure it should be considered deprecated at this point. The runtime and core libraries are now at https://github.com/dotnet/runtime, kinda weird that this is not directly linked in the home page repo.
I like the Stripe API design, and as a follow-on, I tend to like their coding styles and structures. Here's their official Stripe dotnet library - https://github.com/stripe/stripe-dotnet. It's well organized and the code coverage looks good.
Does this, errr, do anything? If it's just a C# adapter for a web api, then it's extremely dull infrastructure code. All you get is code style opinions and folder choices.
I'd argue this library design is fairly ancient in C# land. The reliance on static configuration values goes against modern DI-centric design + integration patterns. It also doesn't have a central entry-point for discoverability and instead expects each internal client to be used directly.
Roslyn is the famous example of a well-maintained C# codebase. But I think it's perhaps too complex to serve as an example. It's hard to get a good overview of exactly what it does.
For some at least slightly smaller and less intimidating codebases, try for example
I have had the pleasure of contributing to a couple different networked drivers with very talented maintainers that I like to use as references.
One supports a wide array of Framework versions and has both Sync and Async I/O, as it must to implement the ADO.NET database driver interfaces. Reading the internals really highlight the way that .NET has evolved over the years and what must be done in each target version to maximize performance:
The other supports .NET 6 only with Async I/O only. This support policy seems to be the way that "modern" .NET development is headed, as .NET 6 will be the floor for LTS .NET (formerly .NET Core) releases in a few months. Async APIs only greatly simplify development, and make it simpler to remain performant when targeting WASM.
As a library maintainer, one thing I often wonder about is how to indicate .NET version support. One option would be for the major version of the library to track the major version of .NET, so if I were to publish a new library today then start with .NET 6 support and start with version number 6.0.0 instead of 1.0.0. This would limit the library to only making breaking changes when the .NET version changes though.
Unless you're being paid by customers with specific needs, or targeting some weird platform, my expectation would be that libraries don't support old .NET versions an instant longer than Microsoft does.
So .NET 6 support can be dropped in late 2024, and I don't think that kind of thing even requires a major version bump. The old framework is dead.
Solutions to Advent of Code problems that people publish on github tend to be fairly short but readable, and most show off the language.
This is not "real" production C# code. Real production code would have a lot more checks for edge conditions and error handling that would obfuscate the meaning. But it's good in order to get a feel for the capabilities of the language and its ecosystem, imo.
There are a couple of repos you can browse, I recommend this one, but only if you have some basic knowledge of LINQ and/or functional programming in general, else this might scare you off. But even if you don't, you could try to figure out how the solution to the first couple of problems in each year work, and learn through that. This guy tries to use the newest features of the language so it can confusing at time. He includes the full text of the problems in the repo so you can try to understand what's he's trying to do.
Just to add to the question. I suspect many developers (and perhaps especially C#) are developing CRUD apps. Are there any public repos that are CRUD apps? It seems like many public C# repos are things like libraries, frameworks, etc.
CRUD apps don't really get open-sourced for several reasons:
(1) CRUD apps tend to be commercial or internal -- most people don't build CRUD apps for fun -- so they're heavily IP-protected.
(2) CRUD apps tend to be highly specific to the way a particular company or department does something, and then require lots of customization on top of that, and then usually don't do their job very well anyway. You wouldn't be able to just grab the code and database schema from the internal support department of some company and use it in your own as-is.
(3) People haven't figured out how to make them highly reusable, such that you could pull a library from NuGet and add a full column of CRUD functionality to another CRUD app. (They haven't figured it out because they're trained in awful, simplistic database practices and design inflexible, fragile, uncuttable, single-use databases, and then design their entire application as a simple layer around that database. And yes, I'm talking about you, dear reader. It's actually astonishing how backward the current standard of database design is.)
That all being said, an actually well-designed, fully fleshed-out CRUD app would be very useful as a reference. Tutorials just never even scratch the surface.
Re (3): Such comments always tickle my curiosity and my thirst for knowledge. So, which books, courses, codebases do you recommend for both beginners and us with beginner's mind that would help us design and build databases which are the opposite of what you describe?
Sonarr/Radarr/Lidarr/Readarr are all open source CRUD apps written in C# (they all fork from Sonarr). Kavita (my open source) app is open source C#/ASP.NET (but probably not a good learning source as I coded while I learned).
But CRUD in general are less popular in Open Source as it has to usually be bundled around some self-hosted app. I think libraries and frameworks are far more common.
One thing that immediately poked my eye is that it's also using MS SQL Server, and I am wondering why it'd be picked over various open source alternatives. My main guess is 'familiarity of the developers', but is there some MS SQL Server capability that is being used that is advantageous for the project? A cursory scan of the code makes it look like fairly simple SQL that would be perfectly at home in just about any RDBMS, and most of the others wouldn't come with the rather high licensing costs.
Don't get me wrong, I think MS SQL Server is a highly capable DB, I just don't see enough of a value add here to justify the price tag, in general.
> Don't get me wrong, I think MS SQL Server is a highly capable DB, I just don't see enough of a value add here to justify the price tag, in general.
I suspect it uses what was called MSDE (MS SQL desktop engine), which is free to use and redistribute on Windows. It is essentially headless SQL Server with most high-end features stripped out and resource governor enabled. With all those limitations it is still very capable (probably too capable for the use case) database.
Same here. As an UO addict, after messing with SphereServer and moving to RunUO, it was my first sight of C# code. Then, it came a looooooong way to here today.
Shameless plug for a site I started aimed at increasing visibility of high quality source code for language learners: http://goodsourcecode.org
It is a proof of concept, and I'm always looking for people to contribute!
I have a suggestion: Could you maybe add some sort of tag cloud, or list, of the current languages in the database? I typed in Javascript, Go, then Python, and no results. Seems like you only have C and PHP in your database at the moment. Listing all of the languages covered by this database would be helpful.
C# is VERY different from even just what things were 2 years ago. You can now build a full-on app with the same number of lines that a Node/Express/Flask app. Except the .NET runtime is about 5-10x faster than those runtimes.