C# 4.0: What’s next

Since I have talked before about Visual Studio 2010 and Dynamic Typing, it is now time to talk about the upcoming C# 4.0 which we are expecting soon.

To understand how C# evolved and what is the paradigm of C# 4.0, let’s get a quick overview of previous versions.

In 1998 the C# began as a simple, modern, object-oriented, and type-safe programming language for the .NET platform. Since launched in the summer of 2000, C# has become one of the most popular programming languages in use today.

With version 2.0 the language evolved to provide support for generics, anonymous methods, iterators, partial types, and nullable types.

When designing version 3.0 of the language the emphasis was to enable LINQ (Language Integrated Query) which required the addition of:

  • Implicitly Typed Local Variables.
  • Extension Methods.
  • Lambda Expressions.
  • Object and Collection Initializers.
  • Anonymous types.
  • Implicitly Typed Arrays.
  • Query Expressions and Expression Trees.

Although C# is an object-oriented programming, but C# 3.0 included some capabilities of functional programming to enable LINQ

In version 4.0 the C# programming language continues to evolve, although this time the C# team were inspired by dynamic languages such as Perl, Python, and Ruby.

Another paradigm that is driving language design and innovation is concurrency and that is a paradigm that has certainly influenced the development of Visual Studio 2010 and the .NET Framework 4.0.

Essentially the C# 4.0 language innovations include:

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

To show these features, I’ll show some examples posted by Doug Holland on his The C# Programming Language Version 4.0 blog post…

Dynamically Typed Objects

In C# today you might need to get an instance of a class and then calls the Add method on that class to get the sum of two integers:

Calculator calc = GetCalculator();
int sum = calc.Add(10,20);

Our code gets all the more interesting if the Calculator class is not statically typed but rather is written in COM, Ruby, Python, or even JavaScript. Even if we knew that the Calculator class is a .NET object but we don’t know specifically which type it is then we would have to use reflection to discover attributes about the type at runtime and then dynamically invoke the Add method.

object calc = GetCalculator();
Type type = calc.GetType();
object result = type.InvokeMember("Add", BindingFlags.InvokeMethod, null,
    new object[] { 10, 20 });
int sum = Convert.ToInt32(result);

With the C# 4.0 we would simply write the following code:

dynamic calc = GetCalculator();
int sum = calc.Add(10,20);

In the above example we are declaring a variable, calc, whose static type is dynamic. We’ll then be using dynamic method invocation to call the Add method and then dynamic conversion to convert the result of the dynamic invocation to a statically typed integer.

Optional and Named Parameters

Another major benefit of using C# 4.0 is that the language now supports optional parameters (like C and C++) and named parameters.

One design pattern you’ll often see as that a particular method is overloaded because the method needs to be called with a variable number of parameters.

In C# 4.0 a method can be refactored to use optional parameters as the following example shows:

public StreamReader OpenTextFile(string path, Encoding encoding =  null, bool
    detectEncoding = false, int bufferSize = 1024) { }

Given this declaration it is now possible to call the OpenTextFile method omitting one or more of the optional parameters.

OpenTextFile("foo.txt", Encoding.UTF8);

It is also possible to use the C# 4.0 support for named parameters and as such the OpenTextFile method can be called omitting one or more of the optional parameters while also specifying another parameter by name.

OpenTextFile("foo.txt", Encoding.UTF8, bufferSize: 1024);

Named arguments must be provided last although when provided they can be provided in any order.

Improved COM Interoperability

When you work with COM interop methods, you had to pass a reference to Missing.Value for unneeded parameters, 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,
    ref missing, ref missing, ref missing);

Now, in C# 4.0 you can only write:

doc.SaveAs(filename);

Notice that you are able to omit the ref modifier although the use of the ref modifier is still required when not performing COM interoperability.

Also it was necessary to ship a Primary Interop Assembly (PIA) along with your managed application. This is not necessary when using C# 4.0 because the compiler will instead inject the interop types directly into the assemblies of your managed application and will only inject those types you’re using and not all of the types found within the PIA.

Safe Co-variance and Contra-variance

Co-variance means that an instance of a subclass can be used when an instance of a parent class is expected, while Contra-variance means that an instance of a super class can be used when an instance of a subclass is expected. When neither is possible, it is called Invariance.

Since version 1.0 arrays in .NET has been co-variant meaning that an array of string can be assigned to an array of object.

string[] strings = new string[] { "Hello" };
object[] objects = names;

Unfortunately arrays in .NET are not safely co-variant. Since objects variable was an array of string the following will succeed.

objects[0] = "Hello World";

Although if an attempt is made to assign an integer to the objects array an ArrayTypeMismatchException is thrown.

objects[0] = 1024;

To achieve safety, both C# 2.0 and C# 3.0 generics are invariant and so a compiler error would result from the following code:

List strings= new List();
List<object> objects = strings;

For the Liskov Substitution Principle (LSP) to be achieved, methods of a derived class need to have contra-variant inputs and co-variant outputs.

Generics with C# 4.0 now support safe co-variance and contra-variance through the use of the in (contra-variant) and out (co-variant) contextual keywords. Let’s take a look at how this changes the definition of the IEnumerable<T> and IEnumerator<T> interfaces.

public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

public interface IEnumerator
{
    T Current { get; }
    bool MoveNext();
}

Given that an IEnumerable collection is read only, there is no ability specified within the interface to insert new elements, it is safe to treat a more derived element as something less derived. With the out contextual keyword we are contractually affirming that IEnumerable<out T> is safely co-variant. We can now write the following code without a compiler error:

IEnumerablestrings = GetStrings();
IEnumerable<object> objects = strings;

Using the in contextual keyword we can achieve safe contra-variance, that is treating something less derived as something more derived.

public interface IComparer
{
    int Compare(T x, T y);
}

Given that IComparer<in T> is safely contra-variant we can now write the following code:

IComparer objectComparer = GetComparer();
IComparer stringComparer = objectComparer;

It is important to notice that co-variance in IEnumerable<object> refers to the fact that its Current property can return a string instead of an object as output, while contra-variance in IComparer<string> refers to the fact that its Compare method can accept an object instead of a string as input.

Delphi is back!

I have started my first years of Windows Development using Delphi (which I call Visual Object Pascal) and I used it for quite few years and within 3 companies before I move to C#.

“Delfee” as pronounced in Greek or “Delf-eye” as pronounced in English was the place of the Oracle in the Greek mythology. That’s why Danny Thrope (Chief Scientist) chose the name to reference it as a language to communicate with the database (Oracle at that time), hence; “If you want to talk to Oracle, go to Delphi”

It is funny to know that Danny left Borland to Google and later to Microsoft, as well as Chuck Jazdzewski (Chief Scientist and Architect), and Anders Hejlsberg (Chief Architect) who moved to Microsoft to be the Lead Architect of the C# team.

The most stable versions of it were 5 and 7 (2002) while other versions did not get much acceptance, specially after the transition to .NET and removing Win32 support. Last I heard about Delphi was that it was going to be sold.

Last week, I found an announcement and I knew the rest of the story. Borland did not get an appropriate offer, so they split the Developer Tools Group into a self-managed company called CodeGear which continued to release Delphi targeting Win32 Development after the inability to compete with C# in .NET development.

Earlier this year, Borland sold CodeGear to Embarcadero Technologies and the later decided to issue two parallel releases, one for Win32 and one for .NET based on Microsoft Visual Studio Shell.

Delphi Prism for .NET is going to compete on the area of cross-platform development as it is going to target development on .NET as well as other non Microsoft operating systems.

Duck Typing

While browsing the net, I found that Typemock Isolator 5.1.1 has been released, which is a mocking framework that I should try one day.

What I’m interested in is its ability to “swap” calls between real and fake objects even if they don’t implement the same interface, like this:

var duck = new Duck(); // The real, untestable class, with a Talk() method
var dummy = new Dummy(); // The fake, testable class, with another Talk() method
Isolate.Swap.CallsOn(duck).WithCallsTo(dummy);
Assert.AreEqual("Quack", dummy.Talk()); // Then the dummy is a duck

I guess the Isolate class is “borrowed” from Ruby, but anyway, it makes testing easier.

This can be possible by applying the concept of “Duck Typing” which was named as James Whitcomb Riley said


If it walks like a duck and quacks like a duck, I would call it a duck

 

So, regardless of the properties and methods of both the dummy and the real duck, a dummy can be considered a duck if it satisfies the properties and methods of a real duck in the current context, or in other words; it does not have to inherit from a duck nor satisfy all behavior of a real duck, but only what we need right now [Talk()]

Duck typing is a principle of Dynamic Typing (Which I plan to blog about next), and it is a heavily used in Dynamic Languages like Python, Ruby.

It is sometimes used in Static Languages, and may be more often than we expect. Here is a blog about Duck Notation in C# in which we find out that iterators in a foreach statement use duck typing. Also in BOO you can define a variable as duck.

Currently there is an open source project to enable duck-typing in C#, and also it is planned to be in the upcoming C# 4.0