Is it just me, or is C# the language to learn if you want to land a software developer role? I think it’s time I dived in to it…
I mean microsoft is “only” absolutely shit, not really in relative terms… Meaning all OSs sucks unfortunately, Windows just sucks the least. Although I dont use another MS software besides windows and office and even office with the new top bar thingy bullshit makes libre office look even better, so I don’t know
I know I’m a bit in a lonely place, here in a java gaming forum, but c# rocks and makes it a lot easier and more fun to program. I don’t say java is bad. But java is very verbose and c# simply has made better design decisions in some places (also worse in others. one think I like better in java is that methods are overridable by default. Prefer itthat way but I understand the reasoning behind the default settings in c#. It makes the developer think more about his public API and what parts can be reused.).
The language itself is great. real generics, reflection of generic information, user defined value types, value types used as generic parameter, properties, var, dynamic, extension methods, first class functions, expression tree, yield, operator overloading. All those features and gimmicks make your life a lot easier if you understand them well and use them at the right places, as you write cleaner, shorter and more readable code.
For game dev I use java, at work I have the pleasure of working with c#, java, groovy, sql, javascript and some other uglier things. Don’t get me wrong. We got shit done in java and we get shit done with c#. But the stuff with c# let’s us concentrate a lot more on the actuall business problems and hides a lot of the technical noise…
The biggest downside for me until now was the lock in on windows. But now that microsoft open sourced most of .net (including the asp.net part) i can finally run an asp server cheaply.
@nerb: here in central europe both java and c# devs are in demand. It feels a bit like the demand for c# .net is a bit higher, but that might be subjective for our company or location.
Verbosity suddenly becomes a great asset when you’ve got to read someone else’s code. Which is what I spend 99% of my coding time doing (usually looking at code the old me wrote, 6 months ago) and I bet you do too.
Cas
I’m the opposite. For code only I’ll read, it tends to be very terse and I inject some comments if I doubt I’ll remember what or why some at some point in the future. I have trouble doing the diagonal scan thing with verbose code.
For me it’s the opposite with java… the relevant business logic is hidden by javas high verbosity which makes it harder to understand what is going on. Less verbosity is not equals less readability. Don’t confuse the two. C# allows you to strip away more than is good. But if you do strip away the right amount you have less but better readable code…
Edit:
Just as an example:
“I have an apple. This apple I have is green. This apple I have has a sour taste. This apple I have has been bought by me for 1 dollar.”
“I have a green, sour tasting apple, that i have bought for 1 dollar.”
Both examples transport the same information, but the first one has just a lot more verbosity, which in turn has a negative impact on the readability. It takes longer to understand the first example, just because you have to read more to get the relevant information. The example is a bit constructed, but having devloped c# and java for some years it is exactly how it feels to me.
I agree that making code less readable is a very bad thing. But in my opinion more verbose code is less readable.
C# wasn’t only aimed at people with a C++/Java background. It was also aimed at people with a Visual Basic background. I suspect that that’s the reason for the naming conventions: the .Net library followed the pre-.Net VB library and the Win32 API in general. (Quite a few parts of the .Net API are just thin wrappers around Win32).
I wonder why people find there to be a distinction between business logic and stuff like “exception handling” and “transactions” and the like… it’s all the same and all as important as anything else. Trying to hide stuff away like that leads to all the most difficult to diagnose bugs that I’ve ever come across. The actual core of the “business logic” as such is usually trivial - like “subtract money from account and ensure it cannot go below zero”, but the devil always hides in the actual details surrounding it. I like to see exactly what’s going on*
Cas
- which leads me to one of my greatest beefs with OOP - encapsulation. In 20 odd years of using OOP I conclude that not being able to see what an implementation is actually up to under the hood is not a good thing.
@cas: you don’t seem to understand my point. If done properly you don’t hide anything (if you are hiding relevant information you are doing it wrong). You just need less code to express the same logic and because of that you need to read less code to understand the underlying logic. It’s as simple as that.
And not sure what projects you worked on, but the example you have given is probably the simplest form of complexity I have come accross in real life. Our business rules/logic are/is a lot more complex in many projects I have worked on.
Well, I’ve worked on rather more complicated stuff to be sure but the rules are rarely significantly more complex than that. Certainly nothing even approaching the complexity of say, a sort algorithm, or a sprite engine.
Maybe someone can give me some examples of this so-called verbosity.
Cas
I can give you a very basic example.
HashMap<SomeUglyType, AnotherUglyLongType> map = new HashMap<SomeUglyType, AnotherUglyLongType>();
Vs
var map = new HashMap<SomeUglyType, AnotherUglyLongType>();
Already an improvement without any information loss. Why do you have to repeat yourself in java? There is absolutely no gain in defining the type twice if the variable holding the value has the same type as the instance being created… still you have to process this information everytime you read the code. This is not a very big thing, but there are many small improvments like that and all those together tend to add up. And when having a very huge code base these small things can matter a huge deal.
I worked on some stuff that might have been more complex than sorting sprites for rendering (management and forecasts for financial portfolios, simulating different investment strategies for said portfolios etc …). As soon as you have to do more than “check that the account is not below 0” it is crucial that the business logic is as clear and readable as possible.
Ofc, in java 7 and onwards you can shorten it somewhat:
HashMap<SomeUglyType, AnotherUglyLongType> map = new HashMap<>();
Project Lombok has val, which essentially works like C#'s var.
@atombrot - seems you may have missed a few changes in Java over the last few years. The <> operator and lambdas in particular make things rather shorter than you might remember from 10 years ago.
As for var… I don’t think it makes much of a useful contribution to the language given the <> operator exists and writing the types out explicitly helps the brain understand what is being written when it is read back. The missing <> operator is a major Achilles heel in the C# language actually, I found myself cursing the lack of it.
Cas
Not entirely correct. You still have to type Map<>. But yes you are right, my java example was worse than it needed to be.
And I’m not advocating var for java. I’m saying that introducing var in C# has resulted in code that is easier to read. As I said. All the small improvements together make the whole package really good.
Yes, lambdas are nice and help improve java. But there is still a long way to go to be en par with c#
I’m still not seeing any significant advantages in C# over Java, syntax-wise. They’re both roughly equivalent, expressively, and indeed as the OP seems to say, some things appear to be different “just because, ner ner ner”. Or possibly to distance it from Java a little further in peoples’ minds.
Cas
Sure, if you limit this discussion to var, there are no big advantages vs java. If you look up the features I listed in my first post you gain a lot more additional fluff and also things that java simply does not support (better generics support/valuetypes, extension methods)
It’s not my (nor is it your) problem that you don’t see the benefits. It’s my gain that I see them and can use them to improve my productivity and the fun factor while coding. Just wanted to share some thoughts that are biased in in the other direction
Well… I’m not trying to limit the discussion to var. I would like someone like you to espouse the benefits of C# so we can see where it’s better.
Cas
One could argue that C# has better support of hardware features and allowing you “step out of the box”. I’m not going to though.
Look at the things I mentioned in my first post. I know that I cannot explain those concepts better than existing resources on the internet.
Some things:
-
Default and named parameters. I like convention over configuration. why do method overloads when you can have your values defaulted to sane values. => http://msdn.microsoft.com/en-us/library/vstudio/dd264739(v=vs.100).aspx
-
Use “yield” for easy implementation of iterators => http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx
-
dynamic type in a statically typed language. http://msdn.microsoft.com/en-us/library/vstudio/dd264736(v=vs.100).aspx
The coalesce operator (??) => http://msdn.microsoft.com/en-us/library/ms173224.aspx
-
Generics information is not erased after compile. Reflection can access the information of the generic types.
-
You can use value types for generics.
-
Properties. I actually like them very much. I find working with properties nicer. objectA.Value = objectB.Value + objectC.Value as opposite to objectA.setValue(objectB.getValue() + objectC.getValue()). But I see that that is just a personal preference.
-
Operator overloading. A controversial one but can be definitely useful.
-
Nullable types (probably would not have much use in java, as you cannot define your own value types) => http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx
-
Extension Methods:
http://msdn.microsoft.com/en-us/library/bb383977.aspx[/url]
A very neat way to extend existing API’s without breaking encapsulation (XD, sorry, had to bring this example). This is extremely helpful if you want to add functionality to an API that you don’t own or cannot change. The .NET library has some very handy extension methods that add functionality very similar to streams (java 8 ), without touching any of the underlying storage classes. A very useful tool. -
The var operator:
http://msdn.microsoft.com/en-us/library/bb383973.aspx
This operator has been received with mixed reactions from the developer community, mainly because it can be abused. As far as I know it only has been introduced to allow anonymous types in the language. But they can be also very useful when having very large types or type definitions with many generics etc. I had the example with the hash map. I come across classes like BackendFormatterKeyChainOperatorImplemenation, sometimes you have even generated classes with much longer names … That is not really a problem of the language, but the var operator helps to cope with the symptoms. I use it often, but only when it is clear what the resulting type is or when it doesn’t matter.
Some of those features are mainly useful for my “boring business work”, but I really miss things like extension methods, default and named parameters, ?? and var. I think there is a reason projects like lombok or xtend exist. Java has room for improvement and I really hope it will improve even further.
Yes, I like a lot of those things.
Because Java is missing them and needs it for performance:
Value types
Especially for reducing a bit of boilerplate and increasing readability:
Default and named parameters
All exceptions are unchecked
Things I’m definitely not keen upon:
The coalesce operator. Co-opting ascii symbols to mean fancy new things is one of the worst aspects of many language, especially as they all like to mean subtly different things. I’m not even a great fan of ? : but I’ve used it for so many years before that I’ve gotten used to it.
var. For various reasons but mostly because it hides stuff I like to know.
Properties. Have a dot operator already. If I mysteriously need to munge values before getting and setting there’s a perfectly good way to do it already - with a method.
Nullable types. Daft idea. We have reference types to do that. Make a reference to a value type. Job done.
Operator overloading. Again with the ascii symbols. I’m in favour of a version that allows normal method identifiers though.
readonly and const (strangely Java has coped without either of these for its entire existence and we’re all still alive)
Things I’m still not sure about:
Extension methods. Seem like a great idea but I started to get an uneasy feeling about them after a while.
Stuff I know nothing about:
Yield.
Dynamic types.
Stuff I don’t care about:
Type erasure. The number of times I need to use reflection in ordinary programming is essentially zero unless I’m doing hax or not doing “ordinary programming”
Things that are in Java which are excellent ideas:
the <> operator, which removes large tracts of crappy redundant typing
static import, ditto
lambda syntax, ditto, plus bells and whistles
final, which works in a lovely consistent way
for instead of foreach. Consistent use of keywords!
Things that could do with adding to Java other than those features mentioned that are nifty about C#:
The elvis operator. I take back what I said about ascii
More type inference and implicit casting
The ability to specify byte and short literals with suffixes a la longs (dunno if C# has these)
Cas