Why I like C#: feature-wise comparison with Java

Recently I was browsing Quora and was quite surprised to stumble upon this question: Java vs C#. Is Microsoft finally closing the gap? I decided to have a closer look and found more of similiar questions there.

Furthermore, at the place where I am currently working at, I am the only person with .NET background amongst mostly JVM people. We are all working on Scala projects and my colleagues are often surprised when I tell them that this or that Scala feature is also available in C#.

This makes me want to write a blog post about how cool a language C# is, especially when compared with Java. I want to underline that I’m speaking only about the language features and not about things like popularity, cross-platformness, ability to deploy easily, etc.

Generics

C# creators were in a great situation since they could learn from Java’s mistakes. They didn’t waste the opportunity and did the right thing. The main problem with Java’s generics is type erasure. The term means that the information about the type parameter of a generic type is not available at runtime. In simple words, this:

…becomes this:

Type erasure makes writing generic types more difficult and less clean. For example, sometimes generic methods have to explicitly take a Class object representing the type parameter (like here).

In C# this is not the case. You can easily access the type of the type parameter:

 

Lambdas, higher-order functions and LINQ

Not long ago I found this article on Hacker News. It discusses some of the new features of Java 8 such as lambdas, streams and functional interfaces. These things are called modern Java whereas in C# they have been available for quite a long time (not to mention that they have been available in Haskell or Ocaml for even longer).

While not everyone has to agree about superiority of functional over imperative programming, it’s hard to disagree that processing collections with higher-order functions (such as map/select or filter/where) is cleaner, less error-prone and much more readable than doing it with loops.

Even though Java has already adopted lambdas and higher-order functions, it seems that C# has better support for them. Examples?

  • In Java 8, you need to convert collections to Stream before calling map or filter
  • C# has built-in syntactic sugar for such opearations which makes such code even more readable and cleaner

 

Type inference

Type inference is a nice feature that allows you not to declare the type of a variable if it’s being initialized on the same line. While it’s not as great as in Scala or Haskell, it certainly lets you cut some boilerplate code. Java does also have some type inference but it is limited to generic methods.

With type inference, the below declaration:

…can be written as:

 

Asynchronous code

C# 5.0 introduced excellent support for asynchronous programming. The async and await keywords let you replace callback-style programming with code that looks exactly as if it were synchronous. It makes the code much cleaner and far easier to read.

The comparison with Java is especially striking if you look at pre-Java 8 code where in order to execute a piece of code asynchronously, you had to create an anounymous type with one method! Have a look at usage of the AsyncHttpClient library:

…and compare it with this C# code:

 

Value types

Value types is part of the reason why there is a C in C#. There are two kinds of types in C# – value types and reference types. Value types differ from reference types mainly in the assignment sementics. When you assign a reference to a new variable, this variable points to the same object. When you assign a value type to a new variable, the whole piece of memory holding the data in the type is copied. This is great for lightweight objects representing data. In some situations it might save you from writing the equals and hashCode operators. What’s more, value types cannot be null which makes them safer than reference types. Finally, value types make primitive types such as int or double more natural.

In Java, every type is a reference type.

Extension methods

Extension methods allow you to add functionality to an object (even if it had already been compiled). One of the cool uses of extension methods is providing a concrete method for an interface. Also, they allow better code reuse and makes it easier to write fluent APIs.

Example of an extension method:

 

C# 6.0 features

Finally, there are many great features introduced in C# 6.0. The language seems to be gravitating towards functional programming, which I think is a good idea, but most of them do not require the programmer to learn a new paradigm. To name some of the most exciting features of C# 6.0:

  • Expression bodied methods – syntax improvment which makes you write shorter code
  • Conditional null operator – which allows writing safer code (which feels like simplified Maybe monad)
  • Expression filters – convenient syntax for exception handling
  • Using static members – again, an improvment to make your code even shorter

 

Conclusion

I have named just a few of the language features of C# which I believe make it a superior language to Java. Obviously, there are many more things to look at when choosing a language than its features. However, I think it’s worth mentioning that thanks to Mono, Xamarin and Microsoft’s BizSpark program for startups, .NET became much more accessible to small companies and startups than it was a decade ago.

Scala for C# developers – part II

This is the second post in the series. Click here to see the previous part.

In the previous post I covered the basics of Scala syntax as well as some comparison of OOP in Scala and C#. Today, I will focus on lambdas and higher-order functions.

Functions as function parameters

You are most likely familiar with lambda expessions in C#. Lambda expression is simply an anonymous function. Lambdas are useful when you want to pass a piece of code as a parameter to some other function. This concept is actually one of the cornerstones of functional programming.

One great example of how useful lambdas are operations on collections. The following piece of code takes a list of integeres, filters out odd numbers and multiplies the remaining numbers by 5.

In Scala, it would look surprisingly similiar:

Scala uses more traditional FP names for map and filter but apart from this, the code looks very similiar. In Scala, we can make it a bit tighter (and less readable):

As you can see, Scala allows you to use anonymous parameters inside anonymous functions. However, be careful when using the underscore notation. The (_ * 5) + _ expression does not translate into x => (x * 5) + x. Instead, the second underscore is assumed to be the second anonymous parameter of the lambda, therefore meaning this: (x, y) => (x * 5) + y.

Returning functions

C# not only allows to have functions which take functions as parameters but also functions that return other functions. In the following piece, the GetMultiplier function takes a single integer and returns a function that can multiply it by any other integer.

Let’s see how would it look in Scala:

Again, it looks fairly similiar. The Function1[Int, Int] has the same semantics as Func%lt;int, int> – it represents a one-argument function that takes an integer and returns an integer. Interestingly, in Scala Function1[Int, Int] can be denoted as Int => Int.

We can go one step further and rewrite the above function as:

This certainly looks odd – our function now has two parameter lists! It is Scala’s special syntax for functions returning functions. You can pass one integer to getMultiplier and what you get is a partially applied function. What is the type of getMultiplier now? It’s Int => (Int => Int) which can also be written simply as Int => Int => Int. This technique is called currying. The idea of currying is that a function with multiple parameters can be treated as a function that takes the first parameter and returns a function that takes a second parameters which returns a function… and so on.