65 comments

[ 2.2 ms ] story [ 98.9 ms ] thread
Operator overloading is super useful - I help maintain FluentCassandra and we overload the implicit conversion operators to make it seamless to convert from built-in .NET types and their associated Cassandra types. It makes a MASSIVE impact on the user experience and amount of boilerplate code it eliminates.
Doing ObjC for the past 5 years, I jumped on the Apple-fanatic bandwagon and hated loudly on operating overloading. But I really really loved being able to use + on two strings. So much nicer than `[a stringByAppendingString: b]`!
Operator overloading is a powerful thing, but C# strikes a balance. It doesn't allow overloading assignment, logical operators and so on. While it should be used carefully, it really makes a difference for scientific types such as vectors.

What I find missing from C# in this area is the use of operators in interfaces, which would let you do truly generic things such as make a matrix class that allows any element type that supports addition and multiplication.

These feel pretty outdated. C# 2, I believe? It has generics and delegates, but none of the things C# is appreciated for these days, such as LINQ, lambdas, async/await, etc.
Is there an updated version with all the new goodies? This is the link that Bing/Google bring me to when typing "C# tutorials".
In fact, there's written "Visual Studio .Net 2003", so pretty outdated I'd say. There are no references about Lamda expressions, LINQ, dynamic support, async support and all the other awesomeness C# gives.
The "Visual Studio .NET 2003" refers to the version of the documentation. If there are different versions you can click on it to see them. Simply go up to the parent page -- you will see an example of this. If you go to the latest version of the parent page then there is no "C# Tutorials" link on it.

Which is to say, newer versions of these tutorials probably do not exist.

In broad strokes, what are the differences between Java and C# and why should I bother with it?

(Disclosure: I hate Java)

C# is years ahead on the language feature side:

- lambdas

- Expression trees

- sensible operator overloading

- value type semantics (you can define your own types that behave like primitives)

- reified generics instead of type erasure, which means that you can have an <int,int> table (just two ints instead two pointers to Integer)

- "async monad" baked into the syntax

On the other hand, Java wins easily on the open source lib count

The way I heard it put some time ago was, Java/JVM couldn't make some important changes because it would break backwards compatibility in an unacceptable way (I'm assuming this means there are mission critical apps written in Java 1 that the whole world depends on), but since C#/.NET were from scratch, they were free from this legacy baggage and could take huge steps forward.
The JVM didn't want to break compat to add generics into the runtime, hence they adopted the erasure model. Other language features are still quite doable on top of the JVM (as evidenced by plenty of more advanced languages targeting the JVM).

Yes, the CLR gets a major advantage by having a better bytecode language design, but it can't be the real reason Java didn't get lambdas until Java 8.

Actually, .NET was in pretty much the same place, because generics were only implemented in .NET 2. They chose to add the support directly to the VM, though and break compatibility.

That being said, Java broke other things along the way back then, if I remember correctly, so in hindsight type erasure for fake generics was maybe not the smartest choice.

Java 8 supports lambdas
I know. But it's not even released yet, and it takes a lot of time for such massive changes to ripple through until you can expect them to be useful for the general public: Developers need to be trained, documentation, tools and libraries updated and hyper conservative tech leads persuaded or dethroned.
I'll give you a broad answer to your question:

C# is a streamlined platform that is designed to work with Microsoft's platforms and tools. If you use what Microsoft has to offer (Visual Studio, Windows, NuGet, IIS, ASP.NET MVC) and some of the really well-maintained OSS packages, you'll have a great experience. Bad news is: you don't get a lot of freedom in terms of platform choice.

Java is a broad platform that comes in thousands of different flavors; there are tons of mature, well-maintained options for just about everything from web framework to IDE to build tool and so forth. The problem is: everyone does everything their own way, so you kind of have to jerryrig everything yourself. Java can feel really janky, but you have a ton of options.

disclosure: I'm ex-Microsoft and LOVE .NET, but I feel that I need to know the JVM better in order to work on some of the projects I love.

I only started using C# because I wanted to write some Windows programs[1]. And just like ObjC for Apple, C# is the primary blessed language of the platform, so if you want to write apps there, you have to use this. But even though I came for the platform, I might stay for the language.

[1]: I'm porting my OS X window manager (https://github.com/sdegutis/zephyros) to Windows.

In my opinion, the best way to see the difference between the two language philosophies is the way compiled programs are started.

[Java] > java SomeRetardedAnd.Inconsistenlty.StructuredNamespace.AndARidiculousClassNameThatHasAnObligatoryOrSuffixLikeForExampleAMotherFckingInflector arg1 arg2 arg3

# wait for what subjectively seems like 20 minutes until JVM starts, 19 if it's Hotshot.

[.Net] > MyProgram.exe arg1 arg2 arg3

Very superficially the languages are very much alike, but somehow C# doesn't manage to get in the way all the time.

Yep, it was just a matter of time before this becomes C# vs Java ... :)
From a distance, C# looks like an incredibly awesome language, but the way it's tied so closely to Visual Studio and Windows really crimps its growth.

I love it's syntax, the libraries look great, and apparently the performance isn't that bad either.

I dunno, I could seriously see myself starting to use Windows full time and writing .NET programs in the near future. This technology (.NET, C#, VS Express) is really handy compared to what I'm used to.
Mono and Xamarin [2] are things you should be looking at.

[1]- http://www.mono-project.com/Main_Page [2]- http://xamarin.com/

I got the impression somehow recently that Mono has become or is becoming somewhat abandoned, which led me to dismiss it. Not sure if it's true or not, but if I thought so, then probably many others do too.
Mono's not been abandoned so much as that its direction has changed. Lately it's been more about native experiences on mobile OSes rather than services running on Linux.

That being said, Xamarin has done an admirable job keeping Mono up-to-date on the latest .NET features lately.

Once we wanted to do app in mono for production, epic fail. Maybe simple apps would do but not if you need WCF which we needed. It had memory leaks and was incomplete just look at WCF site.
Seriously, VS is amazing so I see it as a point in favour more than against. If you worry about the fact that it can cost a lot of money, you can use the Express version that is free and once you get going if you are having some revenue it's a product worth buying.
Fortunately this tutorial is very high-level and assumes you know another high-level programming language, which allows it to keep a quick pace, preventing it from getting too dry or slow.

I submitted it because I read it last night after starting a new C# project, and was quite surprised to see that it wasn't just a strict subset of C like Objective-C is, but it's a whole language of its own, with some additions and changes that I really really like (especially coming from ObjC).

And yes, C# is only really practical for Microsoft's platforms. But the same could be said about Objective-C and Apple's platforms, and yet we don't mind that. Let's not be inconsistent with our biases.

(comment deleted)
> C# is only really practical for Microsoft's platforms.

Not necessarily. If you're doing game development with Unity3D, for example, you're probably going to write much of your game in C#, and it's going to run on Windows, Linux, OS X, Android and iOS.

Wish it was true. It has never been true and it is unlikely to be true in near future. Try some non toy F# on windows and on Mono and you will know. Mono leaks, and if you rely on correct behavior of tail calls, you are in for a lot of grief.
> Wish it was true.

It is true. You appear to be talking about something else.

> C# is only really practical for Microsoft's platforms

Couldn't agree more with that. This is the reason I stick with JVM based languages (Scala, Java) for high level stuff, C/C++ for low level stuff and naturally JavaScript for browser stuff. This pretty much covers everything and at the same time is unbeatable in performance.

Unsafe code( pointers ), shows and example of a copy, where a byte* is casted to a int* and then dereferenced. Such operation in c produces undefined behavior( even if byte points to data large enough ).

Safe or not, does c# consider such dereference as defined behavior?

There is no concept of "dereferencing" in C# because there are no pointers. Technically it is possible to force the environment to allow you to write unsafe code but I've never seen this in reality and I'm having a hard imagining where it would be useful.
One thing where it is useful is manipulating image data. You can get a raw pointer from the Bitmap class you can then manipulate with unsafe code which is orders of magnitude faster than the normal variant. Basically you're saying, for a single method or a block of code "Please turn off all safety nets, but only for these 20 lines". The places where it's useful or necessary are quite few, though.
Top things I miss in C#

- Null coalescing operator

- Tuple Construction/Deconstruction

- Algebraic data types/Pattern matching

- List comprehensions/array slicing

- Operators in interfaces

After 10 years of C# I really feel that F# is the future.

Sorry, I meant a null coalescing property access operator that returns null if the left hand side is null.

Today you write something like this

    var street = (user != null && user.Address != null) ? user.Address.Street : null;
When you could use something like this

    var street = user?.Address?.Street;
Easily solved with an extension method;

    public static TReturn Try<TType, TReturn>(this TType value, Func<TType, TReturn> accessor)
    {
        if (value == null) return default(TReturn);
        return accessor(value);
    }
The compiler should infer the generic types for you:

    var street = user.Try(_ => _.Address).Try(_ => _.Street);
Sure the syntactic sugar is nicer but the extension method's not that much worse.
Yes, I just want the sugar. Also, must not be any slower than the if-then solution of course. If the func calls aren't inlined/removed I don't think it would be good enough perf wise.
(comment deleted)
What exactly do you mean by "Tuple Construction/Deconstruction", honest question ? What's the problem with :

   var t = new Tuple<int, int>(1, 2); 
I apologize if I misunderstood you.
Like in languages like python or most functional languages where you can deconstruct a returned tuple. Imagine a function that returns a point tuple. Instead of this:

  var p = SomeFunc();
  print("X value is "+p.X);
You would do this

  (x, y) = SomeFunc();
  print("X value is "+x);
Ah, I see ! That's pretty awesome. You know Mads Torgersen recently gave a talk on "The Future of C#" in NDC London, he actually mentioned that they're thinking of something like that, I highly recommend you check it out.
I'm still confused by the use of '.' to conflate namespaces & classes, and other things together. A separate character, like ':' or something else would've helped me :)

Or GACs, or finding the right System.Data.SQLite module for your app - http://system.data.sqlite.org/index.html/doc/trunk/www/downl...

Or figuring out how exactly deployments/setups work - where things get put, etc.

I don't know much about java - but it seems easier there - here is the .jar, simple .zip file, look at the manifest - and you are done.

For package management I recommend you use NuGet and you should be good. No need to visit an sqlite website to download anything. Just type

   Install-Package System.Data.SQLite
In your VS package manager console and you are good to go.

Deployment/Setup is not really something C# or .NET cares about, there are many different forms of deployment. (IIS, Windows desktop, ClickOnce, Azure) and in each case you can do it in several different ways. I agree it's tricky to know what goes where sometimes, but it's more a problem with those targets than with how you build the application in question.

On the GAC: Never use the GAC -- except for platform libraries (System.*, etc.).

Always deploy your dependency DLLs side-by-side with your code.

I know that now, but there are still some .NET developers that I meet that think this is the way to go.

Another problem with .NET is that there is a lot to learn, then unlearn - language, api, frameworks, deployment-wise.

That by itself is not bad, if you are an active developer, but if you just given few times a year to fix this and that C# project, then it's a bit more painful.

For example I have to upgrade 32-bit app using Antlr3 and system.data.sqlite (matching 3.7.0.1) to 64-bit, antlr3 newer version and system.data.sqlite (matching 3.8.2) - and after the upgrade there is significant slowdown, and some things do not work (possibly sqlite, but who knows for sure).

DO NOT USE!!

This is from Visual Studio 2003 and will be a terrible, terrible guide. Yes, that's 2003, over a decade ago.

C# programming has moved far away from the Java inspired boiler-plate of that time (as I assume Java has).

For example the properties tutorial is completely wrong as it doesn't include the new simple syntax which you should be using 95% of the time `public string Name { get; set; }`.

Also the way people use objects in C# has fundamentally shifted, in 2003 people didn't really get OO programming or when it was useful so almost everything was an object, frustratingly so at times.

And of course .net 3.5 & 4 have introduced massive programming paradigm shifts, transforming how you write C# completely, which aren't mentioned here, lambda expressions, async/await and extension methods.

(On top of that MS has never been very good at writing good example code anyway, generally use their code as documentation, not as inspiration. Their 'example' projects are often things to be laughed at, not imitated).