Menu

C# > Java

May 22, 2012 - C#, General Computing, Programming, Windows

What does C# have that Java doesn’t?

let’s see:

Operator Overloading.

This was excluded from Java because it’s “Dangerous” or some other bullcrap. Just use the BigInteger class to see what a massive cock-up that decision was.

ref and out parameters

In Java, everything is passed by value. This cannot be changed. The hack to fix this for primitive types is to use one of those stupid boxing classes (Integer for int, Double for double, etc). The justification is that “all functions should only return one type” and that side effects are bad. But programming languages should provide as much capability as possible and sometimes you don’t give a flying fuck if the code is clean, you just want it to work, and having to rewrite some of your codebase because the designers of java decided to take out a few sharp edges is a pain in the ass.

Functions as first class objects.

Every method in C# is an object. you call the method if you add brackets and a parameter list; but if you don’t have brackets, you are referring to the MethodInfo object that represents that method. Methods can accept functions as parameters. Example:

Note also that this is using the => syntax to create a function on the fly. the function could have been defined separately:

What is Java’s Solution to this? Anonymous inner classes and interfaces. personally, I got sick of that with Visual Basic 6. Having to write a new interface to define a single callback method was aggravating and polluted the namespace. Java’s “solution” is anonymous inner classes, which is more a band-aid approach. Java apologists typically respond that “but this way it’s easier to add new methods”. But I don’t want a class. I want a bloody function.

Iterators. Heck that’s what I used above. Notice the yield return and IEnumerable<t> return type? that is quite literally impossible to do in Java. You can’t even fake it, certainly not in a transparent way, and not at all with java; you have to either fake it with some sort of goofy threading thing, which completely defeats the purpose of coroutines/iterators to begin with, which is to avoid the overhead of thread locking and kernel scheduling and be as light and fast as possible. Implementing them with full-on threads with tight restrictions gets rid of all the advantages.

A good case and point. In my game, I use an iterator to go through all the game objects. One of the side effects is that nowhere in that code am I “allowed” to change the collection being iterated over. My resolution involves a queue of delegates being stored as needed, and that queue is emptied at the start of each tick. One such usage is to add GameObjects to the list while that list is being processed:

Can you do this in java? Well, you can fake it with inner classes and passing them around; and then giving it a field to hold that local variable, but what if you want to use other local variables? The above uses two locals- gcp and gstate. Local variables that are used in a lambda are closed over in the delegate and you can access them later. Literally this happens long after that method’s stack has been unwound; the variables that are closed over stay alive until the lambda itself is collected. The Java solution would need a new class that has a field for each “local” you want to use, as well as the logic of the function. What in C# takes a few characters of code in Java would take at least one new source file.

Properties. Oh dear gawd properties. Java’s been faking it for over 20 years with getX() and setX() methods, and that is utterly and completely disgusting. C# implements property support directly into the language. Properties can be on interfaces or abstract classes. They cannot be overriden in the latter case, but one can then define a protected set of virtual accessor methods for derived classes to override that the property routines use. Java’s solution is to let things “pretend” that the set/get accessor pattern is a solution. This property stuff get’s quite involved when we move into C# 4.0 along with XAML, where Dependency Properties provide a lot of notification functionality.

Which brings me to another- Events. Events in C# are defined using a name and a delegate that defines the event signature. Class consumers can then subscribe to that event- multiple consumers can in fact- using either methods of the event or operator overloads. The class can invoke the event and all the subscribed consumers will have their event routines called. This is known as a “multicast delegate” since it calls a number of methods on a single invocation. Java doesn’t have this. Again, the best way to fake events is the same way I used to do it with Visual Basic 6, which was to define an interface. that would allow for a Single “event” subscriber to be assigned, probably using some stupid “setEventX()” accessor. What if you want- you know, actual events with multiple subscribers. Well, thanks to Java’s weak generics implementation, you get to rewrite them for every single event, or use slow reflection to do your dirty work. Neither of which are exactly robust.

You want more? Extension methods. Linq uses these extensively over collection classes, providing a myriad of ways to mess about with them. How about the null coalescing operator ??, or the “as” operator for performing conversions between types and giving null rather than a InvalidCastException if it cannot do so?

Platform Invoke is better than JNI or whatever the fuck it’s called now in Java (JNI? J/Direct? damned if I remember). Of course the argument is that you shouldn’t have to use anything other than Java (or C#) to do something. But you do. That’s how the software ecosystem works. You can’t just hid in the Java sandbox and pretend nothing else exists, because then your UI looks like heap of crap and you end up with something whose features pale in comparison to other products and the only advantage is now you can run it on a Solaris without porting it or something.

Even the for(value:collection) foreach syntax in java was something that took years to get added to the language. The Creators hemmed and hawwed about it for years, as if they were making some life altering decision; because they had to make sure it wasn’t dangerous, right? I don’t even know the state of Closures in Java. Personally I gave up on the language after C# passed it with C# 2.0.

Java is a universally weaker language than C# that offers few real advantages, like comparing a companion cube to a edgeless safety cube, the only difference is that the user can’t hurt themselves. But an experienced programmer trying to stack edgeless safety cubes will find it very frustrating for the very reason that there are no corners.

Have something to say about this post? Comment!

4 thoughts on “C# > Java

pretzelguy1

Well great. Now I feel like I have been wasting my time spending a few hours a week for the past month on Java.
Now I just feel bad.

BC_Programming

Don’t! Java is fine as a language for what it was designed, I just find that it is lacking as far as many design decisions. It is one thing if a language doesn’t have a feature yet- it’s quite another when the language designers purposely leave out the language feature. (this is pretty much the case for a lot of the language features I noted here).

pretzelguy1

Alright, I have heard so many bad things said about it (it being slow and lacking many features) that I was starting to regret the decision to choose that as my first language. I still planned to continue learning after all the time I invested into it but I was still rather regretting the decision.

Anywho, it seems to be good at running on pretty much any OS ( due to the fact that it doesn’t compile into binary but into bytecode that runs on a VM) and I have been seeing that it isn’t all bad. Not to mention even if I had decided to go with the C# route there is a good chance I would end up learning Java anyway. Not to mention Stanford’s tutorials are super awesome and really help explain how everything works.

BC_Programming

Managed Code (Java, C#, VB.NET, Python, etc.) Doesn’t have a significant impact on performance to the point where it is an issue. I’ve certainly never seen a performance problem solved solely by changing the programming language, so people suggesting that rewriting a program in C/C++ will magically make it faster are misguided.

FWIW I learned Java before C# had most of these features (back in C#’s first versions). But I barely used it because I actually found VB6 more flexible language-wise. And I didn’t really like the “java attitude” at the time.

I guess in some ways I simply have faith in the C# language team- their blogs are chock full of good info “Fabulous Adventures in Coding” is by one of the people responsible for parts of the C# compiler, and they explain those questionable design decisions they do make very well. Every new version of the language has big features and the team are excited to talk about all of them as soon as they are allowed to. I haven’t really found an equivalent for Java, and the reasoning for things is usually quite hollow- why doesn’t it have operator overloading is usually answered with something like “because we think it’s dangerous” which is a bit of a non-answer.

Comments are closed.