In part 1, we saw how C# has evolved from its inception in 2000 to the C# 3.0 release in 2008.

C# did not introduce a revolutionary syntax or even revolutionary features. Instead, C# imitated most of its features from C++, Java, Scala, and several other languages. As is the Microsoft way, C# imitated many things but did it better than original. The most outstanding example of that is Generics. Even though Generics existed in Java, C#’s implementation is considerably better ([1]).

C# is not just a series of imitations though. C# 3.0 added some incredible and innovative language features like LINQ, Anonymous Types and Auto-Properties. These creative language features went a long way in increasing C#’s popularity, especially in stark contrast to its main competitor Java, which doesn’t release any major language features from 2004 to 2008.

By 2008, C# gained a lot of popularity and became the 7th most popular language in the world according to the TIOBE index (after Java, C, C++, PHP, Perl, and Python). This is an incredible feat to accomplish in 8 years of existence, this late in the game.

In this article, we’ll follow what’s happened with C# since 2008. We’ll watch a bunch of new competitors rise up and see where C# stands in the popularity contests by the time we get to 2015.

Disclaimer

This is an opinionated article. I will be making judgment calls and categorizing features as “innovations” or “imitations”. I might even call a language “better” or “worse” than another (in some aspects). I’m sure many of you will disagree with some things. Just keep in mind that I’m not claiming anything as the absolute truth and everything written here is my personal opinion.

This article is not meant to be judgmental. I do not mean to say in any way that imitation is a bad thing. Both imitations and innovations are necessary to create a great language.

Another issue is the research here. This is not an academic article and wasn’t written as such. Even though I’ve done pretty thorough research, mistakes could have been made. If you find a mistake in the article, please comment or email me and I’ll correct it as soon as possible.

Alright then, let’s see how C# did after 2008.

C# 4.0

In April 2010, C# 4.0 is released along with .NET 4.0, Visual Studio 2010 and a bunch of new features.

Dynamic binding – C# 4.0 introduces the dynamic keyword. When a type is defined dynamic, the compiler ignores type-checking and instead they are checked at runtime. The motivation here is better interoperability with COM objects.

A very similar feature already exists in Visual Basic. You can use a VB Object with Option Strict Off and it will achieve the same effect. The features are not the same. In VB, you’ll have to specify this option assembly-wide or file-wide. In C#, dynamic is specified per variable. Still, I’ll have to tag this as an Imitation

keyword. When a type is defined dynamic, the compiler ignores type-checking and instead they are checked at runtime. The motivation here is better interoperability with COM objects. A very similar feature already exists in Visual Basic. You can use a VB Object with and it will achieve the same effect. The features are not the same. In VB, you’ll have to specify this option assembly-wide or file-wide. In C#, is specified per variable. Still, I’ll have to tag this as an Named/optional arguments – With Named arguments , we can pass parameters in any order by specifying the parameter name.

1 PrintOrderDetails ( orderNum : 31 , productName : "Red Mug" , sellerName : "Gift Shop" ) ; Optional arguments , we can omit some arguments, as long as we specify a default value.

1 2 3 4 public void ExampleMethod ( int required , string optionalstr = "default string" , int optionalint = 10 ) . . . ExampleMethod ( 12 ) ; Python 1.4.

And here’s an interesting page describing how optional parameters are resolved in 58 existing languages. Imitation

, we can pass parameters in any order by specifying the parameter name. , we can omit some arguments, as long as we specify a default value. Python 1.4. And here’s an interesting page describing how optional parameters are resolved in 58 existing languages. Generic covariant and contravariant – With covariance, we can assign MyClass<Derived> to MyClass<Base> . For example:

1 2 IEnumerable < Derived > d = new List < Derived > ( ) ; IEnumerable < Base > b = d ; Contravariance is a bit more complex. Here’s an example from Microsoft docs: 1 2 3 Action < Base > b = ( target ) = > { Console . WriteLine ( target . GetType ( ) . Name ) ; } ; Action < Derived > d = b ; d ( new Derived ( ) ) ; Covariance and Contravariance are supported in C# for delegates, arrays, and generics. In Java for example, arrays are covariant but Generics aren’t. Scala does support covariance & contravariance, but it seems the support was added after C#. Looking at other languages with Generics: C++ templates do not support variance at all and neither does Delphi. It was hard to research, but it looks like C# is the first language to be able to support variance in generic types and delegates. Innovation

to . For example: Embedded interop types – The compiler identifies the specific interop types you are using, and embeds them into your assembly, omitting everything else. Hanselman explains it well. It’s a nice feature, but it’s not a language feature, so I’ll ignore this one.

C# 4.0 achieves a couple of goals. It catches up with Visual Basic for COM interoperability, which is the reigning king up to now. In addition, C# adds a couple of new features that set it even farther apart from Java (which doesn’t release anything new for a while now by the way).

C# Popularity so far

As far as popularity is concerned, it’s hard to tell but it seems C# became the 3rd or 4th most widely used language in the world around 2012. The TIOBE index shows that between 2010 to 2012 C# is between 4th and 5th place after Java, C, C++ and PHP, with a short jump to 3rd place.

Another popularity index – the PYPL index, crowns C# as the language of the year in 2012. PYPL shows C# and C++ were tied as the 3rd most popular languages after Java and PHP.

Both of these indexes rely on how often a language is searched on Google or Yahoo, which I think can be very misleading. For example, some industries like military branches, block internet access for developers altogether. Maybe those industries would tip the scale towards Java? We have no way of knowing. The PYPL index adds the “tutorial” keyword in their queries, which might add false popularity to new and rising languages. Again, we just don’t know.

Nevertheless, it’s clear that C# is extremely well accepted and is very widely used (probably 5th to 3rd most popular) in the years 2010 to 2012. C# reaches a certain peak in 2012, which it has never reached again up to and including today. Let’s see what happens next.

This is box title [jetpack_subscription_form subscribe_text=”Get notified on new articles about C# and .NET” title=”SUBSCRIBE VIA EMAIL” subscribe_button=”GO”]

C# 5.0

In August 2012, C# 5 and .NET 4.5 were released with a new incredible feature.

synchronous members – The async..await feature revolutionizes asynchronous programming. You are now able to write asynchronous methods in a synchronous style. Beautiful.

1 2 3 4 5 6 using ( var client = new HttpClient ( ) ) { var response = await client . GetAsync ( url , HttpCompletionOption . ResponseContentRead ) ; return await response . Content . ReadAsStringAsync ( ) ; } JavaScript, Python, Kotlin, and other languages. So is the async/await a new C# innovation?

To my surprise, I found out that the answer is no. The async/await is actually largely inspired by F# asynchronous workflows, which was released 3 years earlier. There are some differences in syntax, but overall they are very similar. Imitation 1 2 3 4 5 6 7 8 9 10 11 12 F #: let fetchAsync ( name , url : string ) = async { try let uri = new System . Uri ( url ) let webClient = new WebClient ( ) let ! html = webClient . AsyncDownloadString ( uri ) printfn "Read %d characters for %s" html . Length name with | ex -> printfn "%s" ( ex . Message ) ; } From: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows

JavaScript, Python, Kotlin, and other languages. Caller info attributes – A nice feature for logging or when working with binding frameworks like WPF. 1 2 3 4 5 6 7 8 private void OnPropertyChanged ( [ CallerMemberName ] string propertyName = null ) { PropertyChangedEventHandler handler = PropertyChanged ; if ( handler != null ) { handler ( this , new PropertyChangedEventArgs ( propertyName ) ) ; } } Makes code nicer and saves you writing reflection code. As hard as I looked, I couldn’t find anything equivalent in any other language. This will make it a C# Innovation.

C# 6.0

In 2015, version 6.0 is released with a lot of small, but very convenient features.

Static imports – A syntactic sugar that allows using static methods, without specifying the class name. For example:

1 2 3 4 5 6 7 8 9 10 11 12 using System ; using static System . Math ; public class Circle { public double Radius { get ; set ; } public double Circumference { get { return 2 * Radius * PI ; } } } PI instead of Math.PI . The biggest similarity here is to the already existing F# modules. Modules in F# are implemented as CLR static classes, and can be used this way: 1 2 3 4 5 6 7 8 9 module Math = let add x y = x + y //in another file module Mod = open Math let addFive x = add 5 x I’m sure there are more examples in other languages, but we’ll leave it at that. Imitation

instead of . Exception filters – We can now define a condition on a catch clause, like this: 1 2 3 4 5 6 7 8 try { Foo . DoSomethingThatMightFail ( null ) ; } catch ( MyException ex ) when ( ex . Code == 42 ) { Console . WriteLine ( "Error 42 occurred" ) ; } This is not just syntactic sugar but is also helpful to prevent stack unwinding. This already existed in VB .NET for a few releases. Imitation (Thanks to acelent on Reddit for correction)



Property initializers – This feature was long overdue in my opinion. 1 public bool Enabled { get ; set ; } = true ; Property initializers already exist in F# 3.0, which was released 3 years earlier. Imitation

1 2 F #: memberval X = 0 with get , set

Expression bodied members – Another nice syntactic sugar feature: 1 2 public string GetFullName ( ) = > FirstName + " " + LastName ; public string FullNameProperty = > FirstName + " " + LastName ; I can’t really call this an innovation or an imitation since this just a syntax change for existing features – Methods and Auto-Properties.

Null propagator – This is a great feature that saves writing those endless null-checks 1 2 var minPrice = product ? . PriceBreaks ? [ 0 ] ? . Price ; var result = myDelegate ? . Invoke ( "someArgument" ) ; The Groovy programming language already thought of this a few years back (2007). Imitation

String interpolation – A convenient syntax to write strings with expressions: 1 Console . WriteLine ( $ "Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now." ) ; Again, Groovy beats C# to the punch. This feature exists in other languages like Ruby, and I don’t know who was the original innovator. Definitely isn’t C# on this one though. Imitation

nameof operator – A pretty useful C# Innovation . Allows evaluating the name of a variable, type or member to a constant string at compile time. 1 2 3 4 void foo ( int number ) { Console . WriteLine ( nameof ( foo ) ) ; //-> "foo" Console . WriteLine ( nameof ( number ) ) ; //-> "number" }

. Allows evaluating the name of a variable, type or member to a constant string at compile time. Index initializers – Any class that implements an indexer (like a Dictionary), can be initialized this way: 1 2 3 4 5 6 private Dictionary < int , string > webErrors = new Dictionary < int , string > { [ 404 ] = "Page not Found" , [ 302 ] = "Page moved, but left a forwarding address." , [ 500 ] = "The web server can't come out to play today." } ; Not exactly a revolutionary feature, but can be convenient.

JavaScript object initialization is pretty much the same: 1 2 3 4 5 var obj = { foo : 'some' , bar : 32 , baz : { } } ; I admit JavaScript objects are not the same as C# classes with indexers, but the main use case for this is to initialize C# Dictionaries, which are close enough to call this an Imitation .

Await in catch/finally blocks – We can now use async/await within catch and finally clauses. This is not so much a feature as a solution to a limitation of the original feature, so I won’t mark it as an imitation or innovation.

and clauses. This is not so much a feature as a solution to a limitation of the original feature, so I won’t mark it as an imitation or innovation. Default values for getter-only properties – Turns our property to a sort of read-only field, that will be seen as a property from outside of the class. 1 public string Name { get ; } = "Michael" ; Not so much an innovative feature, as it can be replaced in any other language by a read-only field or const.

By this point, it kind of looks like the C# team is out of grandiose ideas, and they decide to focus on polishing the language. This is not true, as we will see in Part 3 of the series. The truth is that the new C# compiler Roslyn was developed along with C# 6. Roslyn allowed the C# team to easily add those small “low hanging fruit” syntactic sugar features to the language, which was harder to do with the old compiler.

What’s going on in the world when C# 6 is released

The year is 2015, and quite a lot happened in the last few years. Mobile development exploded since 2009 and alongside it, Objective-C, making it the 3rd most popular language in 2015 according to the TIOBE index (after Java and C).

Web development is huge and continues to grow. In 2015, most developers are web-developers according to the Stack Overflow Survey. Accordingly, new programming languages now take the lead in the top. Most importantly, JavaScript. But also, Ruby and Python that gain increasing popularity.

C# makes a lot of decent attempts to win over web developers. These include Silverlight, ASP.NET Web Forms, MVC and Web API. Microsoft is able to win over a lot of the enterprise market but misses on the startup community.

If you’re curious about popularity standings in 2015, the results vary greatly, depending on who you’re asking. The TIOBE index of 2015 says that C is the most popular language, followed by Java, Objective-C, C++, C#, and PHP.

On the other hand, the Stack Overflow Survey clearly places JavaScript as the most widely used language, followed by Java, C#, PHP, Python, C++, C, Ruby, and Objective-C in that order.

Summary

We covered about 5 years of C# progress in this article, from 2010 to C# 6.0 in 2015. The language certainly set itself apart from the initial roots inspired by Java and Delphi. If anything, C# 4.0, 5.0 and 6.0 were largely inspired by F# and Visual Basic .NET.

Another big development is the creation of Roslyn. The new compiler now acts as a service, and provides an API, like the ability to add custom code-analyzers. Perhaps more importantly, the old compiler was rewritten in C# (I assume with fewer problems), which allows the C# team to advance faster. A fact which we already saw with C# 6.0 and will continue to see in future versions.

In Part 3, we’ll see the latest C# versions and also what to expect in future versions.

Share:

Enjoy the blog? I would love you to subscribe! Performance Optimizations in C#: 10 Best Practices (exclusive article) SUBSCRIBE