Speaking as an old C# hand:
1) I don’t think static methods/classes are that big a deal. There’s a free-floating syntax for short scripts but I don’t regard this as much of a problem. There’s also the rarely used using static syntax.
2) The common convention assumes you’re using VS or Rider and can just mouse over to find where things come from. So you’re not missing anything except possibly an IDE.
3) Yeah, it is. But again, the IDE integration is great.
4) can’t argue with you there. The C-style syntax was a mistake that’s been replicated in way too many places.
1) It's just a bit verbose. I think I just rewired my brain around a programming style that is not OOP anymore.
2) As I wrote in another comment, my editor supports hovering with the C# LSP, but after years of reading Python, Go, Rust, and Zig, I got used to be able to see where a name comes from by simply reading it, rather than having to hover over it.
3) My problem with the verbose doc comments is not about writing, but reading.
As you wrote, all of that is not a big deal, but just feels like a step backward.
Yeah static types as containers for functions just means the hierarchy becomes easier. In A.B.C.D() you know A.B is a namespace, C is a type and D() is a static method. With free functions you’d be unsure if this is a free method in the A.B.C namespace or not. Doing reflection over all functions would require iterating types as well as the magical unnamed ”global type”. It’s just a special case that doesn’t carry its own weight. Especially with the newer syntax where you can omit the declaration of the type in top level programs so static void Main() is a valid program.
I don't see how "attaching" functions to types is easier than attaching them directly to namespaces. I don't see either why I would need to use reflection to iterate over all the functions and methods in a namespace, but I agree that if I would need that, then yes it would require adjusting the way it works today. The problem comes from the CLR where all code and data must be part of a class. C# simply mirrors that design choice. That's why C# does not offer free-floating functions. F#, which is also relying on the CLR, solved the problem by introducing the concept of "modules", in addition to the concept of namespaces. Namespaces in F# are like namespaces in C#. All code and data must be part of a module, which is part of a namespace. Under the hood, at the CLR level, modules are implemented as static classes.
> I don't see how "attaching" functions to types is easier than attaching them directly to namespaces.
There's basically no difference between a static class and a namespace, so you're right, it's not easier, but then this kind of dissolves your whole argument too: just put your functions in static class or two, what's the big deal? It's just like a namespace after all.