The question should be "Which language is better suited for modern, typical application development?".
Edit: I addressed some of the comments below. A small remark: consider that when you have a lot of things natively, as idioms, it's a big difference than implementing or downloading and using them yourself every time. Almost everything can be implemented in any of these languages. The question is - what the languages natively provide you with.
So off the top of my head (some arguments apply to both languages)...
C# is better than C++ in that:
- It has native garbage-collection.
- It allows you to treat class-methods' signatures as free functions (i.e. ignoring the statically typed
this
pointer argument), and hence create more dynamic and flexible relationships between classes.edit if you don't know what this means, then try assigning a member method returning void and accepting void to avoid (*ptr)()
variable. C# delegates carry thethis
pointer with them, but the user doesn't always have to care about that. They can just assign avoid()
method of any class to any othervoid()
delegate. - It has a huge standard library with so much useful stuff that's well-implemented and easy to use.
- It allows for both managed and native code blocks.
- Assembly versioning easily remedy DLL hell problems.
- You can set classes, methods and fields to be assembly-internal (which means they are accessible from anywhere within the DLL they're declared in, but not from other assemblies).
C# is better than Java in that:
- Instead of a lot of noise (EJB, private static class implementations, etc) you get elegant and friendly native constructs such as Properties and Events.
- You have real generics (not the bad casting joke that Java calls generics), and you can perform reflection on them.
- It supports native resource-management idioms (the
using
statement). Java 7 is also going to support this, but C# has had it for a way longer time. - It doesn't have checked exceptions :) (debatable whether this is good or bad)
- It's deeply integrated with Windows, if that's what you want.
- It has Lambdas and LINQ, therefore supporting a small amount of functional programming.
- It allows for both generic covariance and contravariance explicitly.
- It has dynamic variables, if you want them.
- Better enumeration support, with the
yield
statement. - It allows you to define new value (or non-reference) types.
Edit - Addressing comments
- I didn't say C++ doesn't support native RAII. I said Java doesn't have it (you have to explicitly do a try/finally). C++ has auto pointers which are great for RAII, and (if you know what you're doing) can also substitute garbage-collection.
- I didn't say anything about emulating free functions. But for example if you need to access a field by a
this
pointer, and bind the method that does it to a generic function pointer (i.e. not in the same class), then there's simply no native way to do it. In C#, you get the for free. You don't even have to know how it works. - By "treating member methods as free functions" I meant that you can't, for example, natively bind a member method to a free function signature, because the member method "secretly" needs the
this
pointer. - The
using
statement, obviously along with IDisposable wrappers, is a great example of RAII. See this link. Consider that you don't need RAII as much in C# as you do in C++, because you have the GC. For the specific times you do need it, you can explicitly use theusing
statement. Another little reminder: freeing memory is an expensive procedure. GC have their performance advantage in a lot of cases (especially when you have lots of memory). Memory won't get leaked, and you won't be spending a lot of time on deallocating. What's more, allocation is faster as well, since you don't allocate memory every time, only once in a while. Callingnew
is simply incrementing a last-object-pointer. - "C# is worse in that it has garbage collection". This is indeed subjective, but as I stated at the top, for most modern, typical application development, garbage collection is one hell of an advantage.
In C++, your choices are either to manually manage your memory usingnew
anddelete
, which empirically always leads to errors here and there, or (with C++11) you can use auto pointers natively, but keep in mind that they add lots and lots of noise to the code. So GC still has an edge there. - "Generics are way weaker than templates" - I just don't know where you got that from. Templates might have their advantages, but in my experience constraints, generic parameter type-checking, contravariance and covariance are much stronger and elegant tools. The strength in templates is that they let you play with the language a bit, which might be cool, but also causes lots of headaches when you want to debug something. So all in all, templates have their nice features, but I find generics more practical and clean.