> * unsigned ints. Even Java's 8 bit byte is signed??!
> * operator overloading, mostly for math like matrices,
vectors, complex numbers
> * ability to write a "swap" function (pass by reference)
These were in from the beginning
> * containers of primitives
Generics (in the proper sense, not the Java sense) came in C# 2.0/.NET 2.0 in 2006.
With those you can make a List<T> and have it backed by an array of primitives that is consecutive in memory. That is, if you make a List<int> it's not a list of some boxed Integer type.
> * compiler that turns readable code into good assembly (no verbose code needed due to simpler
A bit subjective, but I'll argue that the JIT is getting better and is still nowhere near as good as an ahead-of-time compiler that can spend time optimizing the code. The JIT has to be FAST first and foremost since it produces its assembly WHILE the code is already running.
> * destructors that reliably do something at end of scope
There are no destructors and the only deterministic destruction is disposal (via IDisposable). Objects are not freed at that point however. You only use it to free resources, such as deterministically closing a file. The managed object representing the file will sit in memory until the next GC.
The very bleeding edge version of C# yet to be finished will contain a lot more low level C++ like features which will make it more ergonommical to use stack memory (Google "Span<T>"). That will approach some of the C++ use cases.
> no need to write typename twice to create an object
Locals can be implicitly typed. So
var pet = new Dog();
Is an allowed statement inside a method. This came in C#3 in 2007.