Around the year 2000, Microsoft developed the C# language (led by Anders Hejlsberg ). This language, along with the .NET framework had a significant strategic purpose. Microsoft would create a better language tied to Windows, driving customers to the Windows ecosystem and Microsoft products. Perhaps this was part of the notorious Embrace, extend, and extinguish Microsoft strategy (now in the past).
This development came in response to Java, which has gained enormous popularity by then. C# had a great deal in common with Java originally and in fact was called an “imitation” by James Gosling , the creator of the Java language.
Since 2000 and .NET 1.0, C# evolved a great deal, separating itself from Java and becoming one of the most popular languages in the world. This comes with a long list of features over the years that blend together and form today’s C#.
Some of those features were original developments and some were imitations from other languages. Let’s find out the truth.
I don’t mean to imply that imitations are a bad thing. Each successful language relies on building blocks already invented in other languages.
C# 1.0
The first version is released in the year 2002, and includes the following features:
- Classes – Already existed for a while in C++ and Java. Imitation
- Structs – Behave differently than C++ structs, but neither value types and the struct idea by itself are new. Imitation
- Interfaces – Already existed in Java. Imitation
EDIT: Following some misunderstandings, I want to clarify this point: When I write a feature like Classes already existed in Java, I don’t mean to imply that Java was the original inventor of Classes. It’s just one example of a programming language that implements a feature before C#, which shows C# wasn’t the original inventor.
- Delegates
– Not a new concept. C included function pointers at that point, which is basically the same thing. Type-safe function pointers like in C# existed in Algol
back in 1968. Imitation```
public delegate int MathOperation(int x, int y); ```
- Events
– With the Delegates feature, C# is able to implement the observer-pattern
beautifully using Events. Events aren’t new either and already existed in Delphi
. Imitation
```public event EventHandler SomethingHappened; SomethingHappened += OnSomethingHappened; SomethingHappened.Invoke(this, new EventArgs()); ```
- Properties
– An elegant solution to replace the endless getters/setters of Java. Properties already existed in Delphi
though, with a different syntax. Imitation
```private int _number; public int Number { get { return _number; } set { _number = value; } } ```
- Attributes
– A C# Innovation** **that was later imitated by Java in the form of @annotations. ```
[Conditional("DEBUG")] void LogEntry() { // ... } ```
While not mentioned as a language feature, C# being a managed language with a Garbage Collection is an imitation by itself of Java.
C# also seems to be influenced by Delphi. That’s not a coincidence. The lead architect’s Anders Hejlsberg old job was Chief Architect of Delphi.
Despite all the imitations, C# 1.0 implements many features with a nicer syntax and combines everything into an elegant language. All this places C# as a viable alternative to Java.
C# 2.0
In 2005, C# 2.0 is released with new, powerful additions:
-
Generics – Generics were implemented in Java one year earlier in 2004. Even before that, the similar Templates existed in C++. The C# implementation of Generics is better than Java’s, but as a language feature, Generics is an Imitation. ```
List
list = new List (); list.Add(5); ``` -
Partial types – A bit similar to C++, where you can declare all functions in the header file, but implement them in several different files. You still need to have a single header file with all the functions, and this earns C# the Innovation** **status
-
Anonymous methods – With Anonymous methods, C# makes delegates much nicer to work with. It’s not a new concept though, anonymous functions existed in programming for a long that time (for example, in Haskell 98 ). Imitation
<pre class="lang:default decode:true">delegate int Del(int x); Del add5 = delegate(int k) { return k + 5;}; int x = add5(11);//16
-
Nullable types – Nullable types exist kind of naturally in dynamic languages, but it’s a new concept in statically typed languages. It also works great with C# structs. Innovation```
int? number; ```
-
Iterators – At this point iterators are found in C++ STL, Scala , Java and even older languages .
Java released has the enhanced for each loop with J2SE 5.0 one year earlier. What C# innovates is the yield return syntax to create iterable collections. Still, C# is mostly playing catchup here. Imitation
```//Example from Microsoft Docs static void Main() { foreach (int number in SomeNumbers()) { Console.Write(number.ToString() + " "); } // Output: 3 5 8 } public static System.Collections.IEnumerable SomeNumbers() { yield return 3; yield return 5; yield return 8; } ``` ** **
-
Covariance and contravariance – In this version, Covariance and contravariance are supported for objects, arrays, and delegates. So not for Generics yet. Java already supports return type covariance at this time. It’s unclear whether Scala implemented this before C#. Either way, I’ll have to give this the **Imitation **status.
-
Static classes – A static class, that has nothing but static methods/fields/properties is unique to C# at this point. Innovation
In version 2.0, C# didn’t add any meaningful language innovations. C# is playing catching with Java, implementing similar features like Iterators and Generics. However, C#’s implementation and language syntax are superior to the direct competitor. So C# is imitating Java, but doing it better.
C# 3.0
In late 2007, C# 3.0 is released with a boatful of new features.
- Lambda expression
– The lambda expression introduces an elegant syntax to define an anonymous function. Anonymous functions existed in programming much before 2007, but the lambda syntax is relatively new. This syntax becomes so popular that it’s eventually integrated into most popular languages like Ruby, Java, JavaScript, Swift, and C++. ```
(a, b) => a + b ``` But is it innovative? Apparently not. I found that Haskell in [version 98](https://www.haskell.org/tutorial/functions.html) (1998) and **Scala in** [version 1.3.0](https://scala-lang.org/files/archive/old/scala-1.3.0.3.addons/doc/ProgrammingInScala.pdf) (2004) already implement lambda functions with similar syntax. ```
Scala: (x: int, y: int) => x * y Haskell: add = \x y -> x+y ``` **Imitation **
- Extension methods
– We can add functionality to any CLR class from the outside ```
Console.WriteLine("12345".SecondChar());//2 ... public static class StringExtensions { public static char SecondChar(this string str) { return str[2]; } } ``` By this point, this trick is widely used in dynamic languages like **Ruby** and is known as [Monkey Patching](https://en.wikipedia.org/wiki/Monkey_patch). It’s the first of its kind in a strongly typed language like C#. Still, it’s an **Imitation **
- LINQ with Query syntax
– Introducing the LINQ feature. C# allows you to write “queries” on collections and manipulate them with minimal code. ```
IEnumerable
highScoresQuery = from score in scores where score > 80 orderby score descending select score; ``` The query syntax by itself is an imitation of query languages like SQL. But unlike SQL, LINQ is type-safe and the first of its kind in a general-purpose and object-oriented programming language. So even though the syntax is an imitation, I’ll have to give it the **Innovation** status. - LINQ with method syntax – Using Extension methods and Lambdas, C# is able to implement LINQ in a functional programming kind of way: ```
List
scores = new List () {55,65,75,48,35,67,92,75}; var highScoresMethodSyntax = scores.Where(score => score > 80).OrderByDescending(score => score); ``` This turned out to be a game-changing feature for C# and becomes very popular. **Innovation** - Expression trees – This not so much a language feature. It’s a way to add metadata to your LINQ query, which is translated to SQL and eventually executed on the database.
- Anonymous types
– Another innovative C# feature, that works great with LINQ and allows to write pretty elegant code. Innovation```
var productQuery = from prod in products select new { prod.Color, prod.Price }; foreach (var v in productQuery) { Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price); } ```
- Implicitly typed local variables
```
var name = "Michael"; ``` The var keyword was a necessity to support the **Anonymous Types** feature since their type is undefined: ```
var anonym = new {FirstName = "John", LastName = "Smith"}; Console.WriteLine(string.Format("Full name: {0} {1}", anonym.FirstName, anonym.LastName)); ```
The **var** keyword is the first of its kind in strongly-typed languages.Although I didn’t find anything similar initially, it turns out that the programming language [Modula-3](https://en.wikipedia.org/wiki/Modula-3) has a similar [implementation](http://graphics.cs.columbia.edu//modula3/tutorial/www/m3_24.html#SEC24) to c-sharp’s var. Modula-3 was released way back in 1989, which makes it an **Imitation**. *Thanks to Darren Morby for pointing that out.* Eventually, the same feature is adopted by **Java**, **C++** (auto keyword) and **Kotlin**. - Partial methods – Adds to partial types, which were added in C# 2.0. This allows to declare a method in one part of the type, and implement in another. Very much like header files in C++. Imitation
- Object and collection initializers
– A shorter syntax to initialize objects and collections. For example: ```
List
cats = new List { new Cat(){ Name = "Sylvester", Age=8 }, new Cat(){ Name = "Whiskers", Age=2 }, new Cat(){ Name = "Sasha", Age=14 } }; ``` Collection initializers are nothing new. For example, in Scala: ``` val fruit = List("apples", "oranges", "pears"); ``` I didn’t find an equivalent for Object initializers since other languages don’t have Properties and rely on the constructor for such initialization. Overall, it’s an **Imitation.**
- Auto implemented properties
– A short syntax for properties that don’t require field-like logic in their getters and setters. ```
public string Name { get; set; } ``` As mentioned, Properties existed in **Delphi** and at this point in **Visual Basic**. However, auto-implemented properties are a C# **Innovation**. Visual Basic will [imitate](https://www.infoq.com/news/2009/06/Auto-Properties) this a bit later on with .NET 4.0.
In this version, C# adds some major game-changers to the language wars. Specifically, the LINQ feature, along with Lambda expressions become extremely popular.
In stark contrast, the main competitor Java doesn’t release any new language features. Now Java is the one playing catchup, and it will remain so for a long while. For example, Java adds Lambda functions only with Java 8 in 2014.
Summary
Since the initial release in 2002, C# releases three versions and by 2008 it’s a mature language.
C# becomes a major player in the language wars, gaining a big market share.
In 2008, when C# 3.0 is released, Java is the most popular language in the world. According to the TIOBE index , C# is the 7th most popular language at that time (after Java, C, C++, PHP, Perl, and Python).
Check out more C# features and more C# history in Part 2 .
Sources:
EDIT: Thanks to Reddit members pjmlp, SideburnsOfDoom, TriptychButWith8Bits for pointing out some of the innovations were actually imitations (Fixed now).
- C# History – https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history
- Comparison of C# and Java – https://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java
- Java version history – https://en.wikipedia.org/wiki/Java_version_history