Andrew Lock, a .NET developer, writes about ASP.NET Core, .NET internals and Git workflow tips.
HN commenters link his post on git rebase --update-refs as a useful way to work with stacked branches, and cite his .NET guidance.
In the first place this is an error of RTFM kind. The "problem" behaviour is literally documented in the docs. However, in the second place, this is the wrong solution for the original problem. (The author links to https://andrewlock.net/why-is-string-gethashcode-different-each-time-i-run-my-program-in-net-core/ )
The original problem is using linked lists to handle hash collisions. Assuming this is what you want (to keep all values rather than discarding old values, like e.g. Python's dict objects do) obviously you should use a data structure that can handle the case of lots of collisions well, or check your user input.
At the very least the function should have a name that reflects its behaviour, eh? "GetUnguessableHashCode()" or something?
This reminds me of the recent fiasco over in Python land where somebody noticed that int() called on large strings can block the interpreter. The obvious solution is to add an optional timeout parameter (the problem is in the time domain after all.) Instead they added a limit to the size of strings you can pass to int()!
You specified working with web and .NET Core (now just called .NET). Given the scope of modern .NET I don't think I can recommend a single book, but I've tried to order this in how I see them as most to least impactful for a dev.
For web dev specific guidance it's hard to beat ASP.NET Core in Action by Andrew Lock. Check out Lock's blog too at https://andrewlock.net, it's a great source of new features happening in ASP.NET. He does go into publishing an app on both Windows and Linux, with a decent guide to both. But you'll probably want to read through MSDN docs on that as well, I don't think there's a book that goes in very deep on that.
For generally writing modern C# using .NET, I like Code like a Pro in C# by Jort Rodenburg.
For a quick tour of modern C# features C# 12 in a Nutshell by Albahari is basically the reference guide. 12 is the latest, grab any of them from probably 7 up for a decently modern take.
> - Somehow reviewers never seem to like the stack of PRs, my experience is they always react with disdain and/or confusion.
Are people sending multiple branches of the stack for review at once? It should only ever be the "bottom" branch out-for-review at any time.
> - Namely there would be review comments on the first PRs that then cause a cascade of merge conflicts in the follow-on PRs
This can still happen in the model above of course as you need to make changes to the bottom branch in response to review comments/requests.
However, as I noted elsewhere, `--update-refs` is an absolute god-send in those situations: https://andrewlock.net/working-with-stacked-branches-in-git-is-easier-with-update-refs/
It reduces a ton of manual work (scaled by how many branches you have stacked!) to one operation.
Great examples.
Is source generation becoming "trendy"? Microsoft have recently added more of it to C#, in order to support their AOT efforts. It's a bit infrastructure-heavy as it seems to be intended for point support for specific things, rather than a general purpose "write code to generate code" tool. But I wonder if there would be a market for such a thing. The architecture currently does not allow you to edit user source code, just add more code. I.e. it's not a preprocessor, it just has readonly access to the AST.
e.g. the regex generator https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-source-generators
(Reference blog post https://andrewlock.net/creating-a-source-generator-part-1-creating-an-incremental-source-generator/ )
Another related effect of this is Protocol Ossification [0] which happens when implementers of a public API/Protocol surface area take implicit dependencies on common but not standardized behaviors of the API/Protocol implementation.
That being said, you can take proactive steps to defeat this. For example, the default Hash for strings in .NET is randomly seeded each time a process starts[1] in order to strongly dissuade folks from taking an implicit dependency on the underlying algorithm which is not guaranteed to be stable
[0] : https://en.wikipedia.org/wiki/Protocol_ossification
[1] : https://andrewlock.net/why-is-string-gethashcode-different-each-time-i-run-my-program-in-net-core/
You can interactively rebase after the fact while preserving merges even. I usually work these days on stacked branches, and instead of using —-fixup I just commit with a dumb message.
git rebase -i --rebase-merges --keep-base trunk This lets me reorganize commits, edit commit messages, split work into new branches, etc… When I add --update-refs into the mix it lets me do what I read are the biggest workflow improvements from jj, except it’s just git.
This article from Andrew Lock on stacked branches in git was a great inspiration for me, and where I learned about --update-refs:
https://andrewlock.net/working-with-stacked-branches-in-git-is-easier-with-update-refs/