“C# and Java are both nice languages. They reach similar goals through similar means, although C# adds some syntactical touches to Java, such as the foreach keyword and a more pleasant extends/implements construct. Unfortunately, the improvements are outweighed by the instances of regression. In this article, I’ll compare the languages, while trying to avoid dipping to the JVM and CLR level.” Read the article at Builder.com. Update: A similar comparison article, about security.
Goto does exist in Java too. Its called break. Gotos are useful if you use them correctly. For instance, they provide a clean way of breaking out of a deeply nested loop. Take a look at section 14.14 of the Java Language Specification.
SOAP isn’t really integrated into C#. Its integrated into .NET. To say that its tight integration to C# is limiting is plain wrong. C# developers can still choose not to use SOAP.
Aside from that, I agree with most of what the article says.
This article is just propaganda — consider a subtitle like “Java: All the greatness of C++ without the hassle” — and you get the picture…
I’m sorry, but in my opinion the arguments against C# aren’t exactly solid resounding reasons to call it ‘Worse’.
On a different note, operator overloading is the same sort of sin on a more subtle level. When ‘+’ can mean anything depending on the type of the operands, the functioning of code is no longer transparent and unintentional side effects abound.
Excuse me? One of the more powerful languages (for data mining) IMO is K…have you looked at that language? You think C# uses operands in a complex way…..
C# contains a simple mechanism for marking regions of code as unsafe. Within these unsafe regions, the safeguards put in place by Java and later C# to prevent programmers from directly altering memory locations and using point arithmetic are suspect.
I have been programming in C# for a long long time now, and haven’t once needed to handle memory myself. The beauty of .Net is that it offers completely managed code *so you don’t have to*.
This binding to non-.NET objects is similar to the functionality offered by the Java Native Interface (JNI), but it’s more insidious. Whereas JNI was designed to carefully limit the interaction between Java code and native code with well-defined interfaces, .NET makes calling off to native object files so invitingly simple that developers can do so without realizing they’re throwing platform portability out the window in the process.
Ok, so MS have allowed C# programmers to access existing DLLs? And? The .Net framework is windows-only, so why worry about platform portability?
Perhaps the scariest feature in C# is its owner. Microsoft has made a good show of opening up C# and .NET for non-Windows platforms, but it is largely all show. Its CLRs for non-Windows platforms are problematic and buggy
Errrrm….arent most C# and .Net programmers Windows-based? and aren’t the other platforms (apart from BSD) not fully .Net compliant anyway – Mono, the OSS implementation of .Net, isn’t even MS!!
However, the Eclipse IDE, which includes Java support, has pulled ahead of Visual Studio in stability, ease of use, and offered features.
I don’t know where to start. All I can say is you have *got* to be kidding me.
The bottom line, however, is that C# doesn’t do much, if anything, better than Java, and it’s measurably worse in a few areas. When selecting between these two largely identical languages, pick the one that’s slightly better and battle-tested: Java.
As suspected, i can paraphrase this article as:
“I use java, C# is cr*p in my opinion, MS suck, use java”
Nothing of interest to read here, tho thats just my opinion, I just dont go spouting it and attempting to pass it off as a serious article. This guy should try using C# and .Net for a year and see how productive it is. I’m not saying its better than Java, but for a 1.0 release, its pretty darn close.
Having said that, Java will always be *the* server apps language of choice.
It doesnt even touch all the fancy things in C# which would interest me (as I have no C# experience). Stuff like attributes, or semi-stack allocation. Instead it does the usual Java proponent babble that I have heard a thousand times before, like ‘blablabla goto’, ‘blablabla type-safe’, ‘blablabla operator overloading’, ‘blablabla must protect developer from shooting himself in the foot’…
At least the conclusion is honest: if you want a language that is exactly like Java and you hate every single feature that is not in Java, then you should keep using Java…
I have been programming in C# for a long long time now
Hot damn, I didn’t know C# was that old.
Gotos are useful if you use them correctly.
STFU, by your definition everything can be useful if used correctly. Thats the same argument C++ programmers have been making about pointers, yet most modern languages are moving away from pointers and using references.
SOAP isn’t really integrated into C#. Its integrated into .NET. To say that its tight integration to C# is limiting is plain wrong. C# developers can still choose not to use SOAP.
Did you fuckin read the article? The author made the exact point.
If you really disliked the article, and wish to rate it, don’t use the form on builder.com.com, use this one instead:
http://skadus.ath.cx/Builder.htm
It’ll let you rate it at 0, below the normal minimum of 1.
ummm…..refrences are pointers…they both refer to an address in memory.
GOTO’s are good? are you kidding me? talk about spaghetti code.
there is a reason structured programming does not use GOTOs.
sure they are great when you are lazy but they are a painin the butt to debug and to maintain.
Yes, and BREAK is not the same as GOTO.
ummm…..refrences are pointers…they both refer to an address in memory.
references are constant pointers.. big difference
Just use Objective C. Please, I really wish more people would use it.
constant pointer in C++
In Java reference refers to class instances, while C++ pointers refer to memory address.
Get your facts straight
One thing I like about Java and C# is their creators wish to make languages that eliminate things that are easy to misuse and prone to introduce bugs.
Well, why is the goto statement STILL there. You NEVER need goto. Well it’s good to have in situations where very high performance is needed (like a process scheduler etc.) but I don’t think that both of these languages are suited for this.
Operator overloading is very good and make som things easier and doesn’t any complexity in my point of view. Adding two strings together is a very good example of this. It’s easy and intuitive.
I can agree with the author about ‘unsafe’ blocks in C#. MS tries to suit everyone and the language does too much. Introducing managed code into otherwise GC-based code is plain stupid. Java has managed to survive without this feature and I don’t think that C# will kill C/C++ for these situations!
A language like C# need library code to do something useful. Well, the .NETframework is not going to be an ECMA standard. The Mono project is good but without some sort of ‘proof-of-compatability’ I wonder what companies will think about developing .NET applications for other platforms than Windows.
I think C# is a very good language (but it could be better) and the .NET framework is a cliché of a microsoft product – Another HUGE product to be judged by all the developers forced to use it even if they don’t like it. Maybe I’m overreacting a little here;-) I don’t like the framework because its too dependent on Windows technology (no easy task porting it in some aspects) and its too large (typically MS).
C# is like Java (too much perhaps?) and the latter has matured and has a class library which is implemented on many platforms. It also has a wide acceptance in the industry. MS must accept they have lost the monopoly they once had in the PC market. I wish MS had a more opened mind!
All these languages have roughly the same features, roughly the same ‘power’ (see the link at the bottom for my definition of power). The elimination or inclusion of a few extranious features (goto, pointers, etc) is a moot issue. If you are a good programmer you won’t get any significant gain by using any one over the other. It will take you roughly the same amount of time (discounting availability of any 3rd party libraries that already do what you want) to implement anything in any of those languages. That all assumes you are a _good_ programmer.
If you are _not_ a good programmer you can’t be transformed into a good programmer by using a more feature restricted language. You have to study hard and program often to transform yourself into a better programmer.
Here’s a great article that may or may not illustrate my points, but it is certainly worth a read.
http://www.paulgraham.com/paulgraham/avg.html
Hot damn, I didn’t know C# was that old.
Regarding your other replies, this smells just like cynism, so just FYI, some people started screwing around with C# before the .NET framework or the initial VS.NET were final. Both of them were in beta for some longer time.
there are a number of facile and poorly researched viewpoints being peddled in this article that i feel moved to respond to:
1. sloppy syntax pitfalls: the goto statement
is extremely valuable for producing more readable code in a number of cases.
Djikstra’s argued against gotos a long time ago, when sloppy use of this keyword was prevalent. This led to the development of powerful structured programming approaches to replace gotos. However, since then, a number of authors have pointed out the need for gotos to increase the clarity of code. Just a couple of examples:
http://www.flashdaddee.com/Books-Technical/InsideCsharp/ 32ch11d.htm
http://citeseer.nj.nec.com/mcconnell92treebased.html
2. Weaker security.
The author simply failed to understand the C# security mechanism. It’s much more powerful and integrated that offered by Java. In fact, Java has two security mechanisms with overlapping functionality – very confusing. One of the reasons that many people avoid Java for numerical algorithms is its horrendous performance. Sometimes the ability to write optimized code is crucial. Also, take a look at how people are porting C++ toolkits (Gtk,Qt) to C# with ease. This would be torture through the JNI – which is really a low-level C API onto the Java VM – talk about unsafe code! The techniques that C# offers have very important uses.
3. The author fails to mention a number of incredibly powerful features of C#:
Examine Reflection.Emit, Codedom, System.Xml namespaces, the ability to query a graph of objects through XPath, delegates, custom meta-data (Attributes), support for jagged and non-jagged (true multidimensional) arrays. There is so much power here, it’s just very hard to see how Java is going to survive.
This article is one in a long line of shallow treatments of C# and Java comparisons. The author should do his homework.
Forget it man, I’ll take Eiffel over Objective C any day.
here, read this and you decide
http://archive.eiffel.com/doc/manuals/technology/oo_comparison/
Ehm…HOW is the C++/C# extends/implements syntax better than Java´s way of doing the same thing??
I prefer english over stupid shortcuts like “:” any day.
This subject rages on for ages … I’ve never offered my opinion, which was recently enhanced by a friend who pointed something out to me. Alot of people use this crap:
do {
if (err){
break;
}
} while (FALSE);
// do cleanup.
This is obfuscated code. It’s not clear that you’re breaking to go do your cleanup and leave the function, vs. breaking for some other reason … where as this is vastly superior, as it explicitly makes intent clear:
if (err){
goto cleanup;
}
cleanup:
// do cleanup.
This make the code obvious and clear. Anyone who says the first is clearer, is really arguing b/c they learned it that way, and are used to it. Of course the friend who pointed this simple comparison to me, often seems to likes to use like 4 labels in a function, NOW THAT I DON’T LIKE, but to each his own. The goto for the cleanup scenario, is really valueable.
“references are constant pointers.. big difference ”
const int *foo
same damn thing
“constant pointer in C++
In Java reference refers to class instances, while C++ pointers refer to memory address”
and you can use pointers to point to objects in C++.
it is all the same Java just gives you a little abstraction so you don’t have to work with the nitty gritty of the addressing.
Those are two very different function.
break is a very clear command. It is used for breaking out of loops, breaking out of if statements, and breaking out of switch statements. It is not supposed to be used to jump around code, and cannot be used like that. It will go to the next line after the loop/if/switch/etc.
goto is used for jumping around code. It is not intended to be used to jump out of code really, but more to jump around code. It is considered bad coding to use goto to jump around code. You could use a loop and function calls to achieve the same thing, but in a much cleaner and safer fashion.
I agree with you the first example is not good programming.
But I think the other one is not one good example either!
You are modelling something around “invisible blocks”.
Of course it is a matter of taste, but I don’t like to read code where the coder jumps close to anywhere inside a function.
I would probably make the cleanup code a function that would be called in place and then followed by a return or something similar.
But maybe I’ve programmed too much Lisp lately as I would have liked to implement this using recursion. Well, recursion is beatiful. The code gets short and don’t ever get into this battle of gotos!
“1. sloppy syntax pitfalls: the goto statement
is extremely valuable for producing more readable code in a number of cases.
Djikstra’s argued against gotos a long time ago, when sloppy use of this keyword was prevalent. This led to the development of powerful structured programming approaches to replace gotos. However, since then, a number of authors have pointed out the need for gotos to increase the clarity of code.”
I dunno about this point. I will take Djikstra’s side on this one for a while.
you read my mind.
realy, why was goto invented? becasue they did not have a way to make seperate functions and call them so they section off a peice of code with a flag and when you need to use the code you say goto<blah>
so why would you need a goto again? thats right so your program can become unpredictable…gotcha.
I don’t have any C# experience, but I’ve been working in C++ for 5 years and have 1 year of Java experience.
To GOTO or NOT to GOTO
In high level languages like C# and Java, I think GOTO is somewhat out of place. Most of the valid uses of GOTO are handled well by Java’s labelled break/continue mechanism. In C++, GOTO is valid, but only in highly optimized areas of code. I strongly disagree with Voltaire 42’s example. While it may seem clearer at first, it will be much more difficult to maintain. What will it look like when somebody inserts code between the loop and the cleanup: line? The “flow” of the program will be much more difficult to follow.
Operator Overloading
While operator overloading is a “sexy” feature of C++, I honestly haven’t ever found a place where it improves the readability of the code. It brings along with it a whole host of problems (such as making sure a+b == b+a and a++ == ++a. It isn’t rocket science, but it does sometimes involve counterintuitive behavior (especially when overloading non-arithmetic operators). While complex math code makes good use of this feature, but most code is fairly simple logic, not complex math. I just don’t feel that the added complexity is worth it for the 1% of problems out there that benefit from operator overloading.
The operator overloader question really comes down to one’s preference for power/elegance vs. simplicity/consistency. When used properly, these features can produce some wonderfully elegant solutions. However, generally, maintainability is improved when the programmer is restricted to more intuitive and consistent constructs. Neither side is 100% correct, but these feature certainly require a more experienced/skillful developer.
c# is improved language over java. ms saw everything that java did wrong and fixed it. how about little things like SIGNED DATA TYPE? hmm why is that missing from java? is that not boneheaded design decision?
that is not to mention that C# is faster than Java and will soon come with every windows computer on the planet. java on windows is old and decrepit and no one wants to run java applications. with .net u can’t tell u are not running a native application, it is that fast and blends in so well
*sigh*. Gotos have their places, and if used correctly do enhance readability. Did anyone even look at the JLS? Anyway, here’s an example of why gotos are useful, and do not contribute to spaghetti code. Let’s assume that you have a 2D array of names, and you want to go through all elements, looking for the name John.
String[][] names;
int xPos, yPos;
boolean bFound = false;
for(int y = 0; y < names.length; y++)
for(int x = 0; x < names[y].length; x++) {
if(names[y][x].compareTo(“John”) == 0) {
//found John
xPos = x;
yPos = y;
bFound = true;
break exitLoop;
}
}
exitLoop:
That’s in Java. In C++ or C, replace break with goto. If you work with loops within loops, breaks and gotos are useful. The code I presented above is possibly the cleanest way of breaking out of nested loops. The alternative would be to insert numerous boolean checks in the loops themselves, deteriorating performance, and obfuscating the code.
Yes, I do RTFM. Perhaps you should too.
Actually it’s the unsigned datatypes that are missing from Java. In any case, my opinion is that Java and C# are in the same ballpark feature wise, but I’ve seen Microsoft play the old “roach motel” scam far too many times to want to ever invest a significant amount of time and money into something they have so much control over. So, for political reasons, I choose Java (or better still, Python!)
References(in Java) aren’t constant pointers. With constant pointers, you can’t change what the pointer is pointing to. As such, this code would be illegal.
int a = 5, b = 7;
int* const p = &a;
p = &b;//illegal. Changing what pointer points to.
This is totally different from what references are in Java. In Java, references [u]are[/u] pointers. They behave exactly like pointers do, minus the ability to perform pointer arithmatic.
sure, gotos and breaks would be useful in that situation, but you could also just ass in the loop a check for a flag variable and when you find what you are looking for set the flag to what ev er it needs to be to not be valid in the loop test and you break out. is that a little slower? sure. is it harder to read? not if you comment it so taht the reader sees what you did.
good, then I was right in my first post.
so then I will pose to the people that denied what I said:
they are the same damn thing.
goto is one of the best choices available for error handling, expecially in non-GC’d languages where you must deallocate memory if an error condition occurs (so it isn’t as pertainent in languages like Java)
Use of fallthrough to create an easy way to roll back out of a complex function without leaking memory when an error occurs is, in my opinion, good programming practice.
Dijkstra would have the same type of code handled with deeper and deeper nesting. Compare the following:
var0 = allocator();
if(success_condition_one) {
var1 = allocator();
if(success_condition_two) {
var2 = allocator();
if(success_condition_three) {
var3 = allocator();
if(success_condition_four)
return success;
deallocate(var3);
}
deallocate(var2);
}
deallocate(var1);
}
deallocate(var0);
return error;
Deeply nested, ugly, and not very readable. Compare that to this:
var0 = allocator();
if(!success_condition_one)
goto err0;
var1 = allocator();
if(!success_condition_two)
goto err1;
var2 = allocator();
if(!success_condition_three)
goto err2;
var3 = allocator();
if(!success_condition_four)
goto err4;
return success;
err4:
deallocate(var3);
err3:
deallocate(var2);
err2:
deallocate(var1);
err1:
deallocate(var0);
return error;
This doesn’t apply only to dynamic memory, it can apply to any condition in which a function is altering state but an error condition requires the function return the altered state back to its original form before returning, otherwise the object/system is left in an inconsistent state.
There is, of course, another even uglier alternative, and that is to duplicate the error handling code for each branch condition in the latter. The problem then becomes as state changes within a function grow deeper, keeping all of these error handlers consistent becomes much more prone to human error.
I believe the use of goto in these sorts of situations provides the most elegant, readable, and easy to maintain method of error handling.
I keep hearing about how horrible C++ is because it lets you do too much. Maybe you don’t like goto, or reinterpret_cast, or operator overloading, or whatever.
Here’s an idea: don’t use those features! I never do, and C++ hasn’t complained once. If you’re worried that your employees are going to use those features, that’s what code reviews are for. Dock them some pay or something
I think both of those examples are ugly, actually. Try the “Resource Aquisition Is Initialization” meme. Failures should throw exceptions. In C++, destructors are called upon throwing. The destructors should do the cleanup.
The trick is that if and when all the operations succeed, you tell the objects not to destroy themselves when the function exits.
VarCleaner vc0(new Var);
VarCleaner vc1(new Var);
VarCleaner vc2(new Var);
VarCleaner vc3(new Var);
vc0.success();
vc1.success();
vc2.success();
vc3.success();
Much nicer, eh?
OMG that looks terrible But if you’re using C, I suppose that’s what you’re stuck with. But if you’re using C++ or Java, that’s a very clear case for exceptions.
try {
var0 = allocator();
var1 = allocator();
var2 = allocator();
var3 = allocator();
} catch(exception e) {
//exception handling here
//deallocate whatever was allocated.
}
Sure, you could use a boolean flag, but would it be as clear and concise as the labelled break/goto? I have tried numerous ways of breaking out of such loops, and I’ve found gotos/labelled breaks the most clear and concise. Even Bruce Eckel (author of Thinking in C++ and Thinking in Java)agrees on this point, and advocates the use of goto/break in such a manner. It doesn’t create spaghetti code, and you’re not jumping to random places in a program.
The problem with your approach is that the exception handling is potentially ambiguous. I mean, you might be able to tell which variables were inititialized by setting them to 0 beforehand (in C++) and do the right cleanups based on that, but what if the operations were not just simple initializations?
There are many cases where you need to know just how far the process got before it failed. In that manner, Bascule’s approach actually surpasses yours, as pretty as yours may be
How about this instead?
for (int c=0;c<3;c++)
{
var[c]= condition(c);
if (var[c]==0)
return error;
}
return success;
(instead of)
var0 = allocator();
if(success_condition_one) {
var1 = allocator();
if(success_condition_two) {
var2 = allocator();
if(success_condition_three) {
var3 = allocator();
if(success_condition_four)
return success;
deallocate(var3);
}
deallocate(var2);
}
deallocate(var1);
}
deallocate(var0);
return error;
I was assuming that you’d initialise all your variables to NULL, and in the exception handler, you’d deallocate whatever variable was non-null. You’d just call delete, and let the destructor do what ever cleanup is necessary. That way, you’d isolate all the error handling into a separate block of code. It would be both pretty and functional, which is the important thing
Do you have any links to the method you posted? I’m interested in reading up on it. Another reason I like Java. It’s GC’d, variables are set to null (or 0) at declaration, and there’s the finally clause.
for (int c=0;c<3;c++)
{
var[c]= condition(c);
if (var[c]==0)
return error;
}
return success;
That code isn’t going to deallocate whatever was allocated before the failure occured. It’ll just report an error, leaving a memory leak.
would that not be a job more suited to the calling function?
–failed to understand the C# security mechanism. It’s much more powerful and integrated that offered by Java.
Much more? can you tell how more? You only can tell one thing is powerful or not by your purpose.remember, one person’s meal will be another person’s poison.
–ms saw everything that java did wrong and fixed it.
Everything? I think MS is far not the God, and you have no right to name it the name. FIXED–what a great word! Are you blind that can not see so many SPs and flaws come out from MS? Do not tell me you do not know.
–java on windows is old and decrepit and no one wants to run java applications.
Who else think Java on window is OLD? No one?
I think you can never be a good CEO or marketing people. Remember, you can not ask a apple give you a taste of pear—you should at first ask yourself what you really want and what you are doing—that is a good method to tell a person is a fool or not.
But if your goal is just making FUD, maybe you are doing the right things—Most of the folk is always stupid, they need other guys’ brains and eyes.
–for political reasons, I choose Java.
Yeah, also for the freedom! But you know democracy is always low-effective than monocrat–so let us be patient.
Without guns, you still can find many other weapons.
Given machine guns, you can use it as a hammer.
In my opinion, keep it, and use it with enough reason—we need more choice, right?
Sorry, I know I didn’t explain myself very well. I remember seeing an article about it recently…lemme see if I can find it.
In the meantime, here’s a (hopefully) better example.
struct VarCleaner
{
VarCleaner(Var* v) : var(v), ok(false) {}
~VarCleaner() { if(!ok) delete var; }
void success() { ok = true; }
Var* var;
bool ok;
};
VarCleaner vc0(new Var);
VarCleaner vc1(new Var);
vc0.success();
vc1.success();
Admittedly, that’s almost sort of an obfuscated version of what you did…heh. The advantage of having a seperate object comes in when you’re doing things that are more permanent than creating and destroying objects.
For instance, what if you were doing 3 database updates, where failing on any of them would leave the system inconsistent? You can’t undo all the operations in the “catch” clause because you need to know which, if any, were successful. You’d probably also agree that having a bool for every operation is ugly, and having multiple embedded try/catch blocks is even worse.
The trick is to templatize the Cleaner class to accept any undo function and run that upon destruction (unless success() is called), instead of passing it an object to delete upon destruction. Then you can do something like this:
database_operation_1();
Cleaner one(&function_to_undo_operation_1);
database_operation_2();
Cleaner two(&function_to_undo_operation_2);
database_operation_3();
// last op doesn’t need a cleaner
one.success();
two.success();
I think there’s a class out there called ScopeGuard that does something like that. Google should turn something up.
When I used gotos for a finite state machine, it worked out nicely. Using a loop, with a bunch of if- or case-statements inside was ugly in comparison.
How about this instead?
for (int c=0;c<3;c++)
{
var[c]= condition(c);
if (var[c]==0)
return error;
}
Uhh, that was supposed to be an abstract example of mixing branches with state changes that need to be undone in the event of an error.
Here’s some real C code of mine which uses this methodology:
article->poster = (char *)xmalloc(len + 1);
if(read(fd, article->poster, len) < 1)
goto err0;
article->poster[len] = ‘