Archive for the ‘C#’ Tag

The Future of C# … 4.0 and beyond …

anders

As a language, C# has had amazing growth over the years and has become the language of choice for many .NET  developers.  The language itself is really not that old yet it has taken hold as one of the more popular programming languages used around the world.

The evolution of C#

After the initial success of the Java programming language, Microsoft decided to create its own programming language that that could be tailored to its Window’s operating system and more importantly its emerging .NET framework.

This new language, originally called COOL (C-like Object Oriented Language) and later renamed C#,  began its development in early 1999 by Anders Hejlsberg (the chief architect of Borland’s Delphi language) and his team and was publicly announced at the 2000 Microsoft PDC.

Since that time, C# has grown in leaps and bounds having a very interesting evolution.  In brief, the various versions of the C# language have evolved in the following way:

  • C# 1.0 – C# introduced as one of the original .NET Managed Code languages written for the CLR.
  • C# 2.0 – This version started to lay the ground work for the functional features that would be in future releases.  This is the version that brought us Generics.  Unlike C++ Templates, Generics are first class citizens of the CLR. 
  • C# 3.0 – With this version we saw the C# take on features that were much more functional in nature.  The big prize this version brings is LINQ (Language Integrated Query).  LINQ basically builds a functional expression tree that gets lazily executed when its results are needed.  LINQ required an amazing amount of CLR support and makes use of Lambda Expressions which are a functional programming construct.

The Next Release, C# 4.0 – The dynamic C#

While C# 3.0 introduced functional programming concepts into the language, the primary purpose of C# 4.0 is to introduce dynamic programming concepts into the language.  Dynamic programming languages have been around for quite some time including the very popular Javascript language.  In the past couple of years there have been a bunch of other dynamic languages gaining a significant amount of popularity and interest.  Among these are Ruby, whose popularity can be attributed to the popular web platform “Ruby on Rails”, and Python, which is Google’s language of choice for their cloud-based offering. 

Microsoft already has a couple of .NET-based dynamic programming languages, Iron-Ruby and Iron-Python, built on top of the DLR (Dynamic Language Runtime). The DLR is built on top of the CLR and is what makes dynamic languages possible on the .NET platform.  In C# 4.0, the DLR is being leveraged to provide the new dynamic features offered in C# as well as being able to bind to other .NET dynamic languages and technologies, including: Iron-Ruby, Iron-Python, Javascript, Office and COM.  All this is made possible by the following new new features in C# 4.0:

  • Dynamically Typed Objects
  • Optional and Named Parameters
  • Improved COM Interoperability
  • Co- and Contra-variance.

  

Dynamically Typed Objects

Currently in C#, it is fairly difficult to talk to other dynamic languages such as Javascript.  It was also very difficult to talk to COM objects.  Each of these had its own unique way of doing this binding.  To make this more consistent, C# 4.0 has introduced a new static type called “dynamic”.  This sounds pretty funny but it is a way to allow a statically typed language like C# to dynamically bind to dynamic scriptable types in Javascript, Iron-Ruby, Iron-Python, COM, and Office, etc. at runtime.  The dynamic type is essentially telling C# that any method call on a dynamic type is late bound.  This is very similar to the idea of IDispatch in COM.

This “dynamic” type (which is also a keyword in .NET 4.0) is very similar to the “object" type because like “object”, anything can be assigned to a variable of type “dynamic”. In fact, internally to the CLR, the type “dynamic” is actually coded as a type “object” with an additional attribute that tells the CLR that it has dynamic semantics.  So, objects typed as “dynamic” have the compile-time type “dynamic” but they also have an associated “run-time” type that is discovered at runtime.  At runtime, the discovered “run-time” type is actually substituted for the dynamic type and it is the real static type that is operated on.  This allows overloaded operators and methods to work with dynamic types.

The introduction of this new dynamic type is in response to realizing that there are many cases where we need to talk to things that are not statically typed and while this was previously possible it was rather painful.  Some examples of this are:

  • Talking to Javascript from Silverlight C# code
  • Talking to an Iron-Ruby or Iron-Python assembly from a C# assembly
  • Talking to COM from a C# assembly 

Optional and Named Parameters

Optional method parameters is a feature that has been requested for a long time from C++ programmers that have moved to C#.  Similar to C++, optional method parameters allow you to specify default values for parameters  so that they do not need to be specified when calling that method.  In C++, this was a great way to add new parameters to existing methods without breaking existing code.  It also helps to reduce the number of methods that need to be created on a class for common scenarios where you don’t want to make the user of the class have to specify more parameters than are really needed.

To have optional parameters in a method call, you simply add an “= <value>” after the parameter that you want to have a default value.  The only restriction is that the optional parameters have to be at the end of the method signature.  For example:

public StreamReader OpenTextFile(string path, Encoding encoding = null, bool detectEncoding = true, int bufferSize = 1024);

The OpenTextFile method above specifies one required parameter (the path) and three optional parameters. This allows the method to be called by only specifying the path, for example:

StreamReader sr = OpenTextFile(@“C:Temptemp.txt”, Encoding.UTF8);

In this example, the detectEncoding and bufferSize will all be set to the default values specified in the method signature.

This is actually taken one step further by also allowing “Named Parameters”.  What this does is allow you to specify parameters by name when calling a method.  The only restriction is that named parameters need to be specified last when calling a method.  For example, I could also call the above method this way:

StreamReader sr = OpenTextFile(@“C:Temptemp.txt”, Encoding.UTF8, bufferSize: 4096);

Using a named parameter in the example above allowed me to specify the bufferSize without having to specify the detectEncoding parameter.  This does one better than what C++ had to offer.

In fact, you can specify all of the parameters by name in any order (although you must specify all non-optional parameters).  For example, it is possible to call the above method this way:

StreamReader sr = OpenTextFile(bufferSize: 4096, encoding: Encoding.UTF8, path: @“C:Temptemp.txt”);

Improved COM Interoperability

The addition of Named Parameters and the new dynamic type makes COM interop much easier.  Currenlty, calling COM automation interfaces (such as interfaces into Microsoft Office, Visual Studio, etc.) is very clumsy. Many of these interface methods have many parameters.  When calling these you need to specify every one of them as a ref parameter whether you use them or not.  This can lead to code that looks like the following:

object filename = “Test.docx”;
object missing = System.Reflection.Missing.Value;

doc.SaveAs(ref fileName, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

In C# 4.0 this has been made much simpler.  You no longer need to specify all of the missing arguments, this means the above call could be made more simply as:

doc.SaveAs(@”Test.docx”);

What makes the COM interop story better in C# 4.0 is that:

1. For COM only, type ‘object’ is automatically mapped to type ‘dynamic’.

2. You no longer need to specify every parameter as a ‘ref’ parameter (the compiler does this for you).

3. No primary interop assembly is needed.  The compiler can now embed interop types so you do not need the primary interop assembly when you run the application.

4. Optional and named parameters allow you to specify only the parameters that are pertinant in the COM calls.

Co- and Contra-variance

This is a bit more difficult to explain, but I’ll do my best.  In the current C# version, Arrays are said to be “co-variant” because a more derived type of array can be passed where a less derived type is expected.  For example:

string[] strings = GetStringArray();
Process(strings);

where the process method is defined as:

void Process(object[] objects) {…}

The problem with this is that it is not what you would call “safely” co-variant, because if the “Process” method were to replace one of the strings in the array with an object of another type, it would generate a runtime exception (as opposed to a compile time exception).

Likewise, the idea of “contra-variance” means that something of a less derived type can be passed in places where a more derived type is declared.

In the existing C# implementation, Generic types are currently considered “In-variant” types because one generic type cannot be passed in place of another, even if it is more derived.  For instance:

IEnumerable<strings> strings = GetStringList();
Process(strings);

where Process is now defined as:

void Process(IEnumerable<objects> objects) { …}

The above code will not compile because generic types are invariant and must be specified as the exact type.

In C# 4.0, this will be allowed because the compiler would recognize that IEnumerable<T> is a read only type and therefore would not be in danger of being modified at runtime. So, it will be said that IEnumerable<T> will be safely co-variant in C# 4.0.  What makes this possible is that in C# 4.0, IEnumerable<T> is now defined using a new “out” decorator on the T generic type.  So now in C# 4.0 it is defined as:

IEnumerable<out T>

The “out” keyword says that the type T will only be used as an out value and will not be modified.  This will allow the C# compiler to know that this is safey co-variant.  Likewise, using an “in” decorator will tell the compiler that the generic type is safely contra-variant.  This allows all of the proper type checking to occur at compile time.

 

Beyond C# 4.0

Some of the interesting things that are planned for beyond C# 4.0 are features that will make it easier to do code generation and meta-programming (which are things that help contribute to the popularity of such platforms as Ruby on Rails).  The idea of meta-programming is to be able to create executable code from within your application that can get eval’d at runtime.  While this is currently possible doing things like Reflection.Emit, it is very difficult and painful at best with the current C# implementation. To make these very dynamic meta-programming scenarios possible, Microsoft is currently rewriting the C# compiler in Managed code.  This will allow the compiler itself to become a service. 

By rewriting the complier itself from the very blackbox implementation written in C++ to one written in managed code, will allow the compiler to be much more open.  This will allow us to create applications that use meta programming and/or code generation in a way where we can actively participate in the compilation process. Imagine being able to dynamically create rules-based code that can be compiled and evaluated at runtime.  This is sort of analogous to generating SQL programmatically and running it.

This would also expose an object model for C# source code itself.  The possibilities that this will enable will be quite profound.

The Future of C# at the PDC

While at the PDC08, I had the pleasure of attending the session “The Future of C#” given by C# author and architect, Anders Hejlsberg, himself.  It was a great experience to hear about the future of this language from its founder.  In this session Anders goes thru a brief history of C# and where this evolution is heading with C# 4.0.  He does a great job at explaining and demoing these new features.  I highly recommend it.

 The Future of C#    presenter: Anders Hejlsberg

TL16 

WMV-HQ | WMV | MP4 | PPTX

Advertisements