Sunday, 25. November 2007
C# is not Java is not C# is not Java
jlink, 12:43h
Switching regularly between .NET and Java definitely does not facilitate remembering the details of one platform or the other. For me, however, it made me see how similar both platforms are and consider C# to be a (slightly) improved version of Java.
For the most part, I still think that´s true. Explicit properties, delegates and events make coding certain programming idioms somewhat smoother and more readable than using bean conventions and anonymous inner classes. That said, I still shy away from doing serious development with C# since the programming experience and the available tool set is so much worse for C# that it makes me shudder. And yes, I tried many of the 3rd-party add-ons; they can relieve some of the pain but they don't go half the way towards IDEA IntelliJ or Eclipse. To be frank, I haven't used MS Visual Studio 2008 yet, but I cannot imagine Microsoft to really change the equation.
Let's get back to the core topic of this entry. There's one thing where I consider that the designers of Java made a much wiser choice than the C# folks: In Java any
This difference bit me when I wanted to extend a tool that exists in both Java and .NET: FitNesse. FitNesse comes with a
Thus, the seemingly "more secure" design choice of C#'s founding fathers lead to 250 lines of IMHO completely unnecessary duplication. Two reasons for this decision come to mind:
In the end it boils down to a rather fundamental difference in attitude: Should I consider extensibility a basically good thing or do I want to protect developers against their own errors as much as possible? I'm strongly rooted in the first camp because There is no such thing as a foolproof programming language!
For the most part, I still think that´s true. Explicit properties, delegates and events make coding certain programming idioms somewhat smoother and more readable than using bean conventions and anonymous inner classes. That said, I still shy away from doing serious development with C# since the programming experience and the available tool set is so much worse for C# that it makes me shudder. And yes, I tried many of the 3rd-party add-ons; they can relieve some of the pain but they don't go half the way towards IDEA IntelliJ or Eclipse. To be frank, I haven't used MS Visual Studio 2008 yet, but I cannot imagine Microsoft to really change the equation.
Let's get back to the core topic of this entry. There's one thing where I consider that the designers of Java made a much wiser choice than the C# folks: In Java any
public
method which is not declared to be final
is virtual and can be overridden in a subclass. In C# the default assumption is the other way round: Unless you declare a method explicitly to be virtual
it will be statically bound, i.e. a subclass can declare a new
method with the same signature but calling the method on a reference of the superclass will always invoke the superclass's implementation regardless of the object's actual class.This difference bit me when I wanted to extend a tool that exists in both Java and .NET: FitNesse. FitNesse comes with a
TestRunner
to enable running the tests outside the wiki. The implementation (approx. 200 LOC) is very similar in Java and C# and all I wanted to do was to add two lines to a single method:
public class TestRunner... public void Run(string[] args) { ... fitServer.EstablishConnection(MakeHttpRequest()); ... } public string MakeHttpRequest() { string request = "GET /" + pageName + "?responder=fitClient"; ... return request + " HTTP/1.1\r\n\r\n"; }This sounds easy enough, so I created a sublass
public class MyTestRunner : TestRunner... public string MakeHttpRequest() { return base.MakeHttpRequest() + "&myParam=myValue"; }If you replace "base" by "super" and make the M of "MakeHttpRequest" lower case, this solution works as expected in Java. It does not work in C#, though, because my overridden implementation of "MakeHttpRequest" will never be called. Of course, the compiler warned me about that on first build, but since I did not want to change the original library I ended up with copying all code from
TestRunner
into MyTestRunner
plus copying another 40 lines from TestRunnerFixtureListener
into MyTestRunnerFixtureListener
.Thus, the seemingly "more secure" design choice of C#'s founding fathers lead to 250 lines of IMHO completely unnecessary duplication. Two reasons for this decision come to mind:
- Performance: Calling virtual functions is more expensive than statically binding method calls.
- Security: Overriding a method by accident might create harm.
override
keyword, is enough security for my taste.In the end it boils down to a rather fundamental difference in attitude: Should I consider extensibility a basically good thing or do I want to protect developers against their own errors as much as possible? I'm strongly rooted in the first camp because There is no such thing as a foolproof programming language!