Getting into programming the .NET runtime
Based on image in the Microsoft DevBlog "Announcing .NET 8 Preview 1"

Getting into programming the .NET runtime

I've recently made my first contributions to the .NET runtime. Open source development isn't new for me, but contributing to a project of this size and with such an active community certainly was. .NET is the main platform I use, but I never looked further than the projects I build on top of it. Time to dive into the experience that is contributing to .NET!


Every year I've been to Techorama (an IT/.NET conference in the Netherlands, previously Microsoft TechDays), I've gone to sessions by Bart De Smet about new language features and the internals of .NET, just to be blown away by the Just-In-Time (JIT) compiler, intermediate language (IL), memory operations, and the like. After one of those sessions I even attempted to implement a C# language feature myself, only to fail spectacularly.

It did however pique my interest in the underlaying layers of .NET, on which I program daily (mostly on older versions, because industry likes old and stable...). Quite a few years back, Microsoft decided to open source .NET (including the runtime), providing the possibility to take a look at the code, but also to contribute to it: create issues, take part in discussions, and make code contributions.

.NET runtime issues overview: more than 8000 open issues

My first contribution: make a non-nullable property nullable

My first contribution in itself was no big deal (not even a little deal): making a non-nullable string property (that could be null anyway) nullable. It did require going through the process of getting the source code, finding the correct solution to open, build the Common Language Runtime (CLR) and the libraries, make commits and opening a pull request.

After overcoming the first shock of having the build fail when finding out it's certainly not your code that made it fail, it's time to wait for feedback and the changes to be merged. As mentioned: the change was no big deal, so there was no feedback to be implemented. It's only after the changes were merged that my tiny change turned out to be a breaking one...

Turns out that making a non-nullable public property nullable would break existing code when it doesn't expect it to be nullable (causing a warning) and it gets build with warnings-as-errors enabled (please don't have me enable that in projects... ??). Something I wouldn't have thought of myself and luckily for me the friendly folks at Microsoft are handling the documentation process on that one.

This turned out to be a breaking change...

StringBuilder.Replace and ReadOnlySpan<char>, who doesn't use them every day..?

Just like my first contribution, allowing StringBuilder.Replace to be used with ReadOnlySpan<char> arguments is not something I'd use in my daily work. I just picked an issue from the list that looked doable, waited for the proposed API to be reviewed during a livestreamed session by Microsoft developers/architects and went to work.

There was already an existing implementation of StringBuilder.Replace which accepted strings as arguments. As strings are easily convertable to ReadOnlySpan<char>, my implementation changed the existing string argument methods and the underlaying code to take the read-only spans instead of the strings and re-created the string argument methods to call them using .AsSpan() on the strings.

As more code was changed this time around, it attracted more attention and reviews. We use code reviews in my daily work, but they're not quite as meticulous as those from the likes of Stephen Toub (if you have hours to spend, read his famous performance improvements blog ??) and Adam Sitnik . Though while rigorous, they're easy and nice to interact with and very helpful in getting the code to be of the best possible quality.

ThrowIfNullOrEmpty or ThrowIfNull?

As the technical implementation of an existing method changed and the signature of those string argument methods remained the same, I thought it'd be an interesting situation to use benchmarking: the same piece of code (the benchmark) can be run against the .NET 8 runtime and against my build containing my implementation of the methods. Sounds simple enough, but I must admit: I haven't used benchmarking much before and applying it to the .NET runtime took some trial-and-error. Luckily with some instructions from Adam, I made it work.

My basic benchmark indicated the new implementation might be slightly slower than the existing implementation. Not unlogical, as the string has to be converted to a read-only span (or for other reasons, I'm not sure). The issue for which the PR was created wanted the implementation for a different reason, which sadly wasn't easy to benchmark (a "PITA" - technical term ??).

Basic benchmarking results

Adam was nice enough to kindly indicate that the one benchmark wasn't really representative for all use cases and gave some good pointers as to which scenarios to try and which benchmarking settings to use. My more extensive benchmarking results cover those scenarios and paint a more mixed picture as to whether the new implementation is faster than the existing one: in some scenarios it seems to be, in some it doesn't. I'll let the experts working for Microsoft decide whether it's fine to accept the implementation like this, the code itself has already been "LGTM'ed" ("looks good to me").


Starting with the small issues

Small issues. They're worthy of getting worked on too, aren't they? And it's an easy way to get (somewhat) familiar with a codebase you don't know. Not for a moment will I pretend that making one constructor public, fixing the nullability of one property, or implementing two small methods will make a huge difference to the overall experience people will have with .NET. However, it might for the people who created the issues, and it certainly does when it comes to my knowledge of the .NET runtime.


I wasn't sure what to expect when making my first contribution to something as large as the .NET runtime. Would it be a good way to spend my time? What would it bring me as software developer? Were they even going to accept my contributions?

With the few contributions I've made so far, I've noticed it improving my collaboration skills, providing me the satisfaction of getting my code into a big project, and finding out more about concepts like benchmarking. The (Microsoft) people I've come across while collaborating have been friendly, very helpful, and accepting of the contributions I'm making.

Contributing to an active open source project (could be .NET, but could be something else entirely) is something I'd recommend to anyone looking to discover other sides of software development.

Freek Bos

Senior Solution Architect for Production at Lilium specializing in Production Automation

1 年

Max (a.k.a. TheMaximum) is a very skilled professional and I am proud he's part of our team! Great work Max! And fun to read as well.... :)

要查看或添加评论,请登录

Max Klaversma的更多文章

  • Samen plannen we verder.

    Samen plannen we verder.

    In recente jaren heeft Vandoren (voorheen Van Doren Engineers) verschillende bedrijven overgenomen en is mede daardoor…

    5 条评论
  • Scouting anno nu: ook mét droppings en zakmes

    Scouting anno nu: ook mét droppings en zakmes

    Vorige week stond er een goed artikel in het NRC over hoe in ons kleine landje de druk op de openbare ruimte toeneemt…

  • How we overcame the "not invented here syndrome"

    How we overcame the "not invented here syndrome"

    Hindsight is always 20/20. Decisions we now clearly recognize as the wrong ones, were taken with the best intentions.

  • Power your APIs with GraphQL in .NET

    Power your APIs with GraphQL in .NET

    Using GraphQL for your APIs isn't a new thing. Neither is using GraphQL in .

社区洞察

其他会员也浏览了