What does C# have that Java doesn’t?
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.
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.
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.
410 total views, 2 views today