You are looking at it from what you know about C#, the goal is how can you reduce (delete) all this to make the language more accessible.
For you it may be fine to write:
List<string> strs = new List<string>();
And sure if you have been using C# for years you know all the things going on here.
But it shouldn’t be an argument that:
List<string> strs = [];
Is substentionally easier to grasp.
And that has been the theme of all changes.
The example you point out is the advanced case, someone only needs in a very specific case. It does not have a lot todo with learning the language.
The language design team is really making sure that the features work well throughout and I think that does deserve some credit.
That's a basic example with a single level of generics too, you'd sometimes have to do things like:
Dictionary<string, List<Tuple<string, string>>> foo = new Dictionary<string, List<Tuple<string, string>>>
Or things like: Dictionary<string, List<Tuple<string, string>>> foo = DoSomeWork();
And you'd have to get the type right, even though the compiler knew the type, because it'd tell you off for getting it wrong. Sometimes it was easiest to just grab the type from the compiler error. ( This example is of course a bit OTT, and it's a bit of a code-smell to be exposing that detail of typing to consumers. )No-one wants to go back to that, and anyone who says C# is over-complicated I think is forgetting how rough it was in the earliest versions.
While introduction of auto-typing through "var" helped a lot with that, you'd still regularly have to fight if you wanted to properly initialise arrays with values, because the syntax was just not always obvious.
Collection literals are amazing, and now the ability to pass things into the constructor means they can be used when you need constructor parameters too, that's just a good thing as you say.
> The example you point out is the advanced case, someone only needs in a very specific case
This is exactly how C++ landed where it is now. Every time it's "you only need to know that syntax if..." well it ends up everyone has to know that syntax because someone will use it and if you're a responsible programmer you'll end up reading a lot code written from other people.
One issue I have with all these syntax changes is that they are all just more overhead for one to remember. All for what though? Just to just save a few more keystrokes?
I work on multiple applications with different versions of C# and/or Dotnet. I find it quite annoying to have to remember what syntax sugar is allowed in which versions.
If C# did not want verbose syntax, then Java was a poor choice to imitate.
I'm 100% on board with the [] syntax. I'm not on board with adding the syntax for passing arguments to the constructor within that syntax.
I agree that = [] is perfectly fine syntax. But I would definitely argue that:
[with(capacity: values.Length * 2), ..
is non-intuitive and unnecessary. What other language is there that has this syntax? Alternatively, is this a natural way of writing this? I wouldn't say so.
My main language in my free time is Rust, a few years ago it was F#. So, I'm absolutely open to other syntax ideas. But I feel that there has to be a direction, things have to work together to make a language feel coherent.
Another example would be Clojure, which I started learning a few months ago (before we all got swept up in AI FOMO :D). Clojure as a language feels very coherent, very logical. I'm still a beginner, but every time I learn something about it, it just makes sense. It feels as if I could have guessed that it works this way. I don't get that feeling at all in many of the new features of C#.
> The example you point out is the advanced case, someone only needs in a very specific case. It does not have a lot todo with learning the language.
I disagree. When learning the language, you're going to have to read other people's code and understand it. It's the same basic principle, but, I'd argue, much worse in C++. Yes, in theory, you don't have to understand SFINAE and template metaprogramming and (now) concepts and all those things. You could just work in a subset of C++ that doesn't use those things. But in practice, you're always going to have issues if you don't.