For what reasons should I choose C# over Java and C++?
C# seems to be popular these days. I heard that syntactically it is almost the same as Java. Java and C++ have existed for a longer time. For what reasons should I choose C# over Java and C++?
As written the question was a textbook example of not constructive "which language is better?" questions that are off-topic here. I've attempted to make it more constructive with an edit since it actually got good, well thought out answers. Still, please keep the FAQ in mind when asking questions of this nature.
Let me add some edgier items. .NET has a well-defined DOM (*e.g. CodeDOM*) for its language and consequently generating things dynamically at runtime is a lot simpler and more efficient. This can also be helpful as an infrastructural capability. Also, the type system has a 1-to-1 match with all native W3 types. At its core, W3 and other interops were baked into the language from the start. For other languages these concerns were just bolted on, and present many challenges for them. Also, if you'll be interoping with lots of languages and/or protocols then .NET is very strong as well
The real questions is: For what reasons should I choose Nemerle, F* and F# over C#? (i.e., all three languages are from MS and all three are better)
I really don't think any statement of the genre "language/platform X compared to language/platform Y is ALWAYS better" is valid and I also think that for any X and Y it can easily be invalidated for certain contexts. What's the point of this question?
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
thispointer 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 a
void (*ptr)()variable. C# delegates carry the
thispointer with them, but the user doesn't always have to care about that. They can just assign a
void()method of any class to any other
- 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
usingstatement). 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
- 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
thispointer, 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
usingstatement, 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 the
usingstatement. 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. Calling
newis 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 using
delete, 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.
Another important feature in C# compared to Java, for performance reasons, is the "struct", a type of object which can be stored on the stack (or in CPU registers, in special cases) or embedded within other heap objects. They are often used for small objects with 1-4 fields, such as X,Y coordinate pairs.
Disagree the garbage collection has an edge. It is fantastic for simple/medium sized applications and makes it easier for novices. But once you get to complex application you need to understand how the underlying garbage collector works and your applications get as (if not more (subjective opinion)) complex than C++ as you have to work around it.
@LokiAstari Mind explaining? As long as you remember to unregister event handlers and use the Dispose pattern on classes that contain native wrappers, you're going to be fine. That's a lot less to know and remember than memory management in C++.
@LokiAstari Please elaborate. In my firm we're developing an extremely large critical application and the GC is a treat. Actually, in my experience, constant allocating/freeing is cumulatively much slower than the every-once-in-a-while GC games.
The garbage collector is optimized for **general** usage. When you start stressing the system (i.e. having memory usage that pattern that does not fit into what was optimized for) then it does not cope as well (thus it is fine for simple/Medium sized applications). Thus if you build big server applications that stretch the system you need to know much more than a normal C++ developer.
@YamMarcovic: Sorry cant tell your the details. But at the time I was working for MS for a service associated to Bing for mobile content delivery that required excessively quick response times due to the load. We spent a lot of time understanding the garbage collector and working with/around it.
@Qwertie: IMO, struct isn't that important, a struct is 99% a class with a slight difference; like any optimizations options, it is the job of the compiler/JIT -- not the programmer -- to figure out when a data structure could be optimized to be stored on the stack or registers or embedded in another class instead of the heap.
"Java 7 is also going to"?? It's been officially released for nearly half a year now...
Never heard of `std::function` and `std::bind` and lambdas? C++ has these things too, y'know.
@DeadMG It'll take a while before you can really say C++ practically "has" these things. My compiler (from Debian Squeeze) doesn't support lambdas.
+1 for mentioning linq and lamdas. I'd like to point out that XAML is kina awesome for designing a gui.
-1 since I am missing the sections "C++ is better than C# in that..." and "Java is better than C# ...". I do not think C# is superior in all areas so an answer without these two sections is probably lacking some important information.
@DeadMG: I think functional programming in C++ sucks big time but I do not consider C# to be better than C++ because it has better lambdas (the latest cool feature that every programming language must have to be considered modern): I think C++ and C# serve different niches and programming styles and these comparisons are a bit artificial.
@Giorgio I pretty much agree with you there. Except that I do think C++ functional programming *is* cool and helps a lot.
@Yam Marcovic: I do not think C++ functional programming is cool either: I would never consider C++ for doing FP.
@Giorgio Well I was only speaking of lambdas and higher order functions. If you don't think that qualifies for functional programming, I wouldn't really argue.
@Yam Marcovic: Having done some FP in other languages I find some of the C++ syntax really clumsy (e.g. `std::transform()`) and the semantics not very robust (e.g. you risk a crash if you do not use lambdas properly). One thing one does quite often in FP is to create a closure and return it as a value, which needs extra care in C++ (to avoid a crash as soon as you invoke the closure). So I'd rather use others languages for FP.
@Giorgio That's not a drawback of C++ though. That's the very intent of it. Manual memory management. It depends on your needs. It's not simply a matter of "they didn't do it as good as other languages."
As a Java developer I am kinda offended with those correct statements :) I wish Java had all those goodness.
In C#, all class instance methods are non-virtual (non-overridable) by default. In Java, all class instances methods are virtual (overridable) by default, which in my opinion opens up your Java libraries to an enormous amount of ad-hoc, willy-nilly, silly overrides by your customers which in turn makes it more difficult for you to make non-breaking changes going forward, unless you remember to explicitly mark all your methods as final. In C#, only the ones you explicitly want to allow to be overridden can be.
.NET Framework and Windows clients
Windows is the dominating Operating System on client computers. The best GUI frameworks for Windows applications is Winforms and WPF together with .NET Framework. The best programming language to work with the .NET Framework and it's APIs is C#. Java is not an alternative for this. And C++ is an older language without automatic memory management. C# is similar to C++ but has automatic memory management and you don't have to work with pointers, which make you more productive. C++ can still be the best option for some cases, but not for form-intensive database applications that is common in business.
IIS and Windows Server
If you are used to work in the Windows environment and with C#, you will need the least investment to learn IIS for server programming and Windows Server for basic administration.
Active Directory and Windows Server
If you are developing software that is going to be deployed in company networks, it's likely that they use an Windows centered environment using a Windows Server with Active Directory. In such an environment it's easist to integrate and deploy an solution made in C# and .NET Framework.
Personally, I'm a Java developer, not a C# developer, but I work with the web. I would switch to C# if I were developing network applications for Windows network. But I prefer Java for Linux based web servers. I would choose C++ for embedded systems were I don't won't many dependecies.
Yes, C# is a better language with more modern features than C++ and Java, but that is not the most important thing for choosing C#.
The environment for your software is most important for choosing C#. If you work in an environment with Windows clients, Windows servers, Active Directory, IIS and maybe SQL Server then C# is the far best language with the .NET Framework.
If you work in a Unix environment with e.g. web services, Java would be my choice. And if you work with embedded systems or have to integrate with hardware devices C++ would be a good choice.
You can certainly use .NET on other platforms via Mono, MonoTouch and MonoDroid, but my benchmarks found Mono to be significantly slower than .NET for Windows, and Microsoft's own Compact Framework is extremely slow on Windows CE: http://www.codeproject.com/KB/cross-platform/BenchmarkCppVsDotNet.aspx ... of course, WPF is only available on Windows (but I don't like it anyway.)
Which dependencies do you mean wich "I would choose C++ for embedded systems were I don't won't many dependecies." Do you mean the java libraries?
C# and Java
C# is a very good language if:
- You want to do general purpose object oriented development. It's a classic, statically typed OOP language.
- You are targeting Microsoft platforms only (it's worth remembering that Microsoft effectively cloned Java to create C# because they wanted a Java-like language that would lock people into Windows. They could have used Java, but that would have enabled people to easily run applications on other platforms....)
C# as a language is nicer than Java in various ways (better syntax for properties, value types, reified generics etc.). I prefer C# as a language to Java but in the grand scheme of things they are fairly similar languages and suitable for similar applications.
On the other hand, Java has some big advantages as well:
- Huge open source ecosystem - the libraries for Java that you can get for free are by far the best of any language. It is hard to overstate the importance of this - from the point of getting things done, Java is very effective.
- Tools - the Java tools are in my view better than what you can get the the .Net world. e.g. Maven (once you have mastered it!) is particularly impressive.
- Maintainability - Java has been around a while and has been successful in big companies precisely because it is relatively stable and there has been a lot of effort put into backwards compatibility. The simple and slightly verbose syntax also helps Java here - it's easier to read and maintain code if the code is very clear and explicit.
- New languages - The JVM has some amazing new languages (Scala, Clojure, Groovy etc.) that are the future of the Java platform. This is where much of the language innovation is happening, and it's happening much faster than in either Java or C#.
So Java vs. C# is a pretty close call and it really comes down to whether you want to be in the Microsoft camp or the Open Source / cross-platform camp.
Personally, I prefer Java because:
- The library ecosystem is in my view much more important that the fact that C# has nicer syntax than Java
- In the long run, I want all my code to be properly cross-platform and able to run on big clusters of cheap linux machines on the cloud.
- Clojure is IMHO the most promising language in the world right now, and if I stick with the JVM platform I'll be able to transition my code and skills easily into Clojure over time.
C/C++ is basically a different beast entirely. I would not recommend it for general purpose application development nowadays for the following reasons:
- Memory management - for most general purpose programming nowadays, you don't want to be managing your own memory. Garbage collection in C# or Java is much better for your productivity and sanity than any of the explicit memory management techniques you will have to use in C/C++
- Complexity - C++ in particular is an extremely complex language. It takes a long time to master and the code itself can also be fiendishly complex. (C++ templates for example are particularly hairy....)
- Productivity - most of the time and all else being equal it will take you longer to get things done in C/C++.
However it is undoubtably a great choice in a certain limited number of special domains, in particular:
- Operating systems - you probably want to use C/C++ if you are writing an operating system.
- Games development - nearly all the best commercial game engines are C/C++. It's still the best choice if you are developing a demanding AAA title (C# and Java are perfectly fine for less demanding / casual games)
- High performance computing - optimised C/C++ is probably the best way to create very high performance code. For most applications doing this level of optimisation isn't worth the effort, but in certain domains it can be extremely valuable (high frequency trading for example)
- Hardware access - You need direct access to the hardware (e.g. for an embedded system)
So basically, C/C++ is a great choice if and only if you are focused on one of the domains where it is particularly well suited.
You mention maven as an example of better tools for java. I'm not particularly famialr with it, but looking at the documentation, Maven looks srather similar to the native .Net build tool MSBuild. What makes Maven better than MSBuild?
MSBuild is much closer to Ant, i.e. a way of writing build scripts. Maven does full lifecycle management of every artifact in your project, including automatically resolving, fetching and caching all library dependencies from Maven Central, and even running your deployment to a live production environment. Since Maven is declarative rather than imperative, you don't need to give build "instructions" - it works out exactly what needs to be done from the definition of the project in the pom.xml - it's like magic sometimes.
+! (just because I only have one vote): you have explained very well why the Java ecosystem is better and why one should not compare only the syntax of C# vs Java. Java has more and better libraries and tools. Not much is happening in the Java language itself, but new very interesting languages are appearing for the JVM that are (IMO) much more interesting than C#. I do not know Clojure but I find Scala very interesting: designed to be OOP + FP from the beginning.
why is it that everyone thinks C++ code is full of manual memory management. Its not C you know, RAII means you almost never have to manually allocate/free memory (the times you do are the ones where a language like C# would be useless to you).
@gbjbaanb - probably because RAII is inadequate for general purpose memory management. It is in no way equivalent in flexibility to a full GC system like you see in Java or C#. As soon as you go beyond the bounds of RAII, you are back in manual memory management territory.
I heard that syntactically they are almost the same.
Syntactically? Who gives a flying monkeys about syntax? Syntax is good for only one thing: allowing faster migration from syntactically similar languages. That's it.
C# is vastly better than Java. Consider their generic and functional programming support- C# is way ahead of Java. Not to mention operator overloads, and other good stuff- C# is vastly better featured. There's no way that Java could possibly be considered better than C#.
C++ and C# is more of a contest. C++ has an incredibly annoying archaic compilation model and a bunch of legacy diseases from C, but it's templates are vastly more powerful than generics, and it's resource managing approaches are much more flexible and powerful in general, as
usingis a complete failure, and it executes faster.
I think one should compare both language features and the availability of a language on different platforms. With C# one is locked in with Microsoft, with Java one is not: that's a big advantage, at least for UNIX / Linux developers. OOP + FP are cool features but why bother about C# if you can use Scala, which runs on the JVM and can interface with legacy Java code? I would never learn a platform-specific language unless I am forced to.
@Giorgio: The Mono project does exist. But secondly, Microsoft actually takes care of their platform- they give it regular large upgrades. Java has hardly had anything new. Also, the question is about C# vs Java, not CLR vs JVM.
If you want something much more powerful than that unfortunate C++ templates abomination, take a look at Nemerle.
@DeadMG: As far as I know I cannot take any C# program developed on Windows and build it with Mono. Not CLR vs JVM? The question is about why people use C# or Java. For people to use a language they need a runtime and an operating system. I do not discuss about the fact that C# has more features than Java, but Java is much more portable: this is factor that can influence adoption of a language. In fact Java is still used much more often than C# even if it lacks certain advanced features.
@Giorgio, you *can* take any C# program and build it with Mono. You cannot use certain libraries (which are not parts of the C# language anyway). And java is not "much more portable". You can code for iOS in C#, but not in Java, for example.
@SK-logic: By "more portable" I meant that there is a standard Java platform (JDK) that is available for more operating systems than its C# counterpart. I did not mean that the JDK is available for **all** operating systems. IMO this wider availability of a standard development kit can at least partially explain why Java is still more popular than C#.
Java rund on platforme mono don't. One major advantage there on those platforms.
@SK-logic: I did not mean the compiler alone, I meant the standard libraries too: Swing, JDBC, RMI, etc. I often think that Java is not the best language around, but when I need to get something done, I can often find a **very good**, free Java library for it which will run unchanged on different OS's. I may be wrong, but to my knowledge the C# ecosystem (as they call it) has still to catch up on this. These factors can also influence adoption of one language or another.
There are certainly libraries you can't use with Mono, especially the newest stuff written by Microsoft such as WPF and WCF (I understand Mono only has rudimentary WCF support, and although there's no WPF you can use Moonlight (=Silverlight) which is similar). But Mono provides all the basics; after writing a benchmarking program that targeted .NET, I tried it with Mono (Windows version) and the same binary (exe file) Just Worked with no changes, including P/Invokes to a C++ DLL that I wrote. Also, Mono's Windows Forms support is listed as "complete": http://www.mono-project.com/WinForms
-1 for using strong language and sweeping judgments in an otherwise productive discussion on real, specific engineering differences.
C#has some nice built-in features like
LINQand delegates. It is getting the best from both worlds -
C++. Look here for a full comparison.
But I like the
Javaworld better - much more open source frameworks and it runs on every platform. And don't tell me about
Mono- it is not a reliable option.
+1: "But I like the Java world better - much more open source frameworks and it runs on every platform." Let's hope Oracle does not change this!
It doesn't have the best of both worlds at all. Enforced-GC, `using` is a failure, relatively slow execution, weak generics, I'd hardly call that the "best" of C++.
@DeadMG - Of course every language has its uses. `C++` has more power at a price of harder development. What I meant with "from both worlds" was that `C#` has combined some nice features from both languages. Not that it is better in all things. Hope it is clear now:)
@SK-logic - Every time I try to run a complex application under `Mono`, I receive some nice exceptions at different stages. You can't rely on it for an application of a critical importance.
@Petar Minchev, It is nothing but your own fault. You must follow the portability guidelines and you should not use non-portable libraries - and this way any complex application would run reliably with Mono. Things like WPF will *never* be ported.
@SK-logic - Yes, but when I am using Java(without `JNI` of course), I don't care about portability.
@SK-logic - Also not complex `Windows Forms` project has failed under `Mono` too. There are too many bugs, if you look at the bugtracker.
@Petar Minchev, there are many non-portable Java libraries out there. You must always be cautious about portability, no matter whatever language you're using. And anyway, the question is about the languages, not the third party libraries.
@SK-logic: Can you name a few non-portable Java libraries? I once developed a complete Java application (ULC + JDBC + Oracle) on Linux and deployed under Windows XP with PostGreSQL. Did not change one line of code.
According to some sources (see e.g. http://www.indeed.com/jobtrends) C# is still less popular than Java, and as popular as C++.
C# does provide features that Java lacks, e.g. direct support for certain programming idioms like properties, functional programming style, and so on. C# has a higher level of abstraction than C++, which is an advantage when development time is more important that program speed.
Personally, I still prefer the Java / C++ worlds. As Petar Minchev said, Java has more open-source frameworks and applications, it runs everywhere, is less tied to a particular vendor and operating system. C++ has similar advantages, even though code often needs adaptations going from one platform to another. Since I prefer to develop on Linux and, to my knowledge, I cannot have fully fledged C# on Linux, I never got a real interest in C# because my programming needs are covered by C, C++, Java, Scala.
On the other hand, for many developers being tied to a particular vendor is not a problem: Microsoft has a dominant position in the operating system market and C# gives lots of job opportunities. Therefore, IMO many developers adopt C# because, besides being a feature-rich language, it is also a good investment.
"I cannot have fully fledged C# on Linux" - Could you elaborate on this? Do you mean that the full .Net framework isn't available because I haven't run into any issues with the C# language itself (or F# for that matter) on Linux?
@wawa: To my knowledge the .Net framework corresponds to the JDK, and the .Net framework is only available for Windows whereas the JDK is available for several OS's. If this is not correct I can edit my answer (and change my opinion as well).
I think a closer analogy would be the Base Class Library to the JDK. The BCL has standardized and unstandardized parts. The mono project implements the standardized as well as much of the unstandardized pieces.
What about "Which Software Development Framework, that includes a programming language" its better ?
You forgot to include other stuff, like the "environment" you will work with.
Are you going to work only for Windows O.S., but, doesn't have to be low level, and have a lot of memory and other resources ?
Choose .NET as framework over Windows, and use C#.
Are you going to work only for Windows, but, doesn't have to be low level, BUT, doesn't have a lot of resources ?
Choose the Delphi Framework (and Object Pascal Delphi programming language or Lazarus Object Pascal programming language)
Is your app. required to support several platforms, like a game, in different mobiles ?
Choose the Java Framework, and the Java programming language.
Is it Linux with KDE as graphic interface ?
Choose QT framework, with C++
Is it Linux with Gnome as graphic interface ?
Choose GObject/GLib framework, with C++
Are you going to work with a lot of low level operations, like developing drivers?
Plain C or C++ its used for several Operating Systems, with standard libraries, as a framework.
Just my 2 cents.
I'm not sure about 3. Smartphones are very popular today and AFAIK, all of them support C# in some form, but only Android supports Java.
@svick: That is a lie. Aside from Android, Java also exist in some form on iOS, Symbian, WinMo, Blackberry, Maemo, and WebOS (i.e. everything that matters or still matters; don't get me started with even smaller platforms). Android, Blackberry, and Symbian **officially** supports Java as development option; Sun used to support Java on iOS even while Apple does not fancy it. Java is the **primary** development language in Android and Blackberry phone. I can't say the same with C#, AFAICT it's only officially supported on WinMo.
If you do a search you are likely to stumble upon discussion on top programming languages. Here is one of the search results - http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html - Java still seems to be the most popular language.
Java tried to remove some of the shortcomings of C++ (and making the programmers life simpler for non-real-time and non-critical applications). C# being the late-comer to the party, avoided some of the shortcomings of the Java language. C# has made a lot of progress (as Microsoft has lot of control over it) while advances in Java were blocked for a considerable period of time due to conflict between it's stakeholders.
A couple of things that have not already been mentioned:
C# is better than C++ because:
It does away with header files, which translates to great simplicity.
C# is better than Java because:
It supports both reference-type (class) and value-type (struct) user-defined types, which, if you know what you are doing, can yield significant performance benefits.
It supports delegates, which are like single-method interfaces, thus greatly simplifying the coding of frequently occurring constructs that involve single-method objects.
Can you explain in which way having both reference-type and value-type types can yield performance benefits in C#?
For example, if you want to have an array of records, in Java you have no option but to describe your record using a class, so your array will be an array of references to a multitude of separately allocated objects. In C# you can describe your record using a struct, so your array will be just a single continuous area of memory containing your structures one after the other, just as in C.
As another example, if you want to define a small new type, (a type which would fit within a machine word,) you do not have to define a new class for it; you can simply make it a struct, so it will be obeying value semantics. Passing such structs around will not be more expensive than passing around references to objects, but you will have the benefit of not allocating, constructing, and garbage-collecting any objects.
I understand. So classes are instantiated on the heap and accessed through references while structs are instantiated on the stack (?)
Almost correct. The only inaccuracy in this statement is that a struct will be found on the heap if it is embedded inside another object, or if it is inside an array of structs. And it will also be found on the heap if it ever gets boxed, in exactly the same way as value types are boxed in Java.
And then there is the ref keyword in C#, which allows you to pass a reference to a structure for a method to process, even though the structure is a value type. Cool stuff!
I understand the advantages and optimizations that one can do by using structs. So, in a sense, C# lies between Java and C++: Java has a simpler, more abstract model, C# has a more pragmatic approach allowing for more optimizations due to the way data is represented internally. What I mean: structs do not add to the expressiveness of the language (classes would be enough for that) but they give some extra possibilities to optimize.
Well, yes, that's correct. The language constructs that make C# more expressive than Java are other things, like Linq, `using`, `yield`, `async`, etc. I agree that struct is not one of them. I could even admit that `delegate` is not one of them either, because a delegate is equivalent to (actually less useful than) a single-method interface.
You should chose the best language for your expected environment and your expertise.
Chose C# if you are working in a Microsoft only environment. While C# is standardized under ISO/IEC 23270:2003, Microsoft's version remains the only complete implementation. Several key parts of the language are not covered by the standard and are thus subject to Microsoft's patents. No one else will implement a completely compatible version of the language for other systems, so in effect, you are vendor locked to Microsoft Windows and .Net for as long as you use the language. If you are looking for skills to use in the mobile market, best to look to another language.
Java works, but has a good deal of overhead, in part due to such features as garbage collection. Java is also not standardized by ISO/IEC, so you have no guarantees if you switch platforms and versions of Java, only Sun/Oracle's best intentions. If you are eventually planning to work with Android, this is definitely the way to go. Android's programming is basically Java, with a few changes.
C++ is standardized and almost all compilers follow the international standard, so you have guaranteed behavior BUT the language does not protect you from yourself. You have to perform cleanup and overflow checking on your own. This is not hard. C/C++ programmers have been doing these for many years. Apple uses Objective C for everything, so if you want to aim for Apple, I recommend you try this instead.
If you see yourself leaving Windows behind at some point, I'd suggest learning both C/C++ and Java - both of which are marketable at this time.