Freigeben über


Anders Hejlsberg Introduces C# 4.0 at PDC 2008

Anders Hejlsberg presented a fascinating and entertaining session at PDC 2008 on C# 4.0.  He talked about dynamic typing, optional and named parameters, improved COM interoperability, and improved support for co-variance and contra-variance.  These language improvements are very cool – they enable us to write code that more closely expresses our intent, with less syntactic noise.  Carve out some time, and watch his PDC session.  Anders is a dynamic presenter, so you won’t be bored!

Dynamic Typing

This blog is inactive.
New blog: EricWhite.com/blog

Blog TOCThese guys are brilliant.  To support dynamic typing, they have introduced the concept of “statically declaring an object to be a dynamic type.”  This allows them to add dynamic typing to a language that is strongly focused on all of the goodness that a statically typed language brings.  A dynamic type is just like the “object” type, except with dynamic semantics - member resolution is deferred to runtime.

Perhaps the strongest motivation for dynamic typing is interoperability with dynamically typed languages such as Python, Ruby, and JavaScript.  But there are a number of scenarios where you are programming against constructs that are inherently dynamically typed – XML, databases, COM – to list three – that benefit from dynamic typing.  And some people feel that they are more productive when prototyping with a dynamic language, and these new language features support them.

One of the most interesting parts of the talk is where he introduced the concept of an interface, IDynamicObject.  When you write a class that implements this interface, you can write your own code to get or set members.  In his talk, he showed a small class that wraps a Dictionary, allowing you to set or get ‘properties’ – you are actually setting or getting items in the dictionary.  Cool.

You also have the ability to treat statically typed objects as dynamic types, and the language will use reflection (with smart caching for performance) to resolve members at runtime.  This allows you to write code that is very ‘Python Like’ or ‘Ruby Like’.  So, for example, you could write code like this:

public class Product
{
public string Name { get; set; }
public int Age { get; set; }
}

class Program
{
static void Print(dynamic x)
{
Console.WriteLine("Name: {0}", x.Name);
Console.WriteLine("Age: {1}", x.Age);
}

static void Main(string[] args)
{
Product p = new Product()
{
Name = "Bob",
Age = 45
};

Print(p);
}
}

Optional and Named Parameters

I remember some time ago, I saw a study about developer preferences.  Some developers prefer to design classes that can never be in an invalid state, so will write constructors that take a number of parameters, and the object returned from the constructor will always have all required members initialized.  They will prefer to construct an object like this:

Product p = new Product("Bob", 45);

However, if, in order to construct a valid object, you must specify a large number of parameters, this leads to somewhat unreadable code.  I can’t remember if the xyz parameter is the fourth or fifth parameter to the constructor, and end up relying on Intellisense and tooltips in Visual Studio to tell me which parameters are which.

Other developers prefer to see code that is more readable.  However, in the following example, if the Product class requires that the Name and Age properties must always be set, the object p is invalid between the point where it is constructed, and the properties are initialized.

Product p = new Product();
p.Name = "Bob";
p.Age = 45;

With named parameters, you have the best of both worlds.  You can write it like this:

Product p = new Product(
Name: "Bob",
Age: 45
);

You get the readability where you can see the parameter names for all values passed to the constructor, and you can write the constructor to enforce invariants.

Optional parameters (which have been around for some time in VB) also remove syntactic noise.

Improved COM Interoperability

They have improved the semantics when importing a COM interface.  This combined with the new dynamic typing capabilities and optional parameters results in significantly cleaner code when interacting with COM.  In his video, Anders automates Office.  He first shows the code as you would need to code it now.  Then he cleans it up using the new language features.  The difference is dramatic.

Co-Variance and Contra-Variance

In his talk, Anders provides a concise explanation of C# 4.0’s improved support for co-variance and contra-variance.  This is a feature (most appreciated by language geeks) that makes the language behave more like we would expect it to in some circumstances involving generic types.  Co-variance and contra-variance are two special cases where it is safe to treat a more derived closed type as a less derived closed type.  (A closed type is a type where you have supplied a type for a generic type parameter – List<T> is an open generic type – List<int> is a closed type of List<T>.)  We can tell the compiler additional information about the use of type parameters, and the compiler can then understand when it is safe to convert a more derived closed type to a less derived closed type.  Currently, there are some scenarios where you are forced to use a less type-safe approach.  With C# 4.0, these scenarios will become type safe.

I personally ran into this recently when I was writing a little text parser where the structure of the code was parallel to a little grammar that I had defined.  I could implement it, but only in a way that was not type-safe.

This is a language feature that will be most appreciated by developers writing more complex class hierarchies that make use of generics.  It will impact the rest of us who write code that uses those class hierarchies.

Comments

  • Anonymous
    November 04, 2008
    PingBack from http://kintespace.com/rasxlog/?p=1210

  • Anonymous
    December 09, 2008
    why not use an interface instead of a the "dynamic" type?

  • Anonymous
    December 09, 2008
    is this considered duck typing?  is there situation outside of COM+ where this is useful?

  • Anonymous
    March 09, 2009
    >>why not use an interface instead of a the "dynamic" type? Because its easier to write "dynamic", then to implement several interfaces.

  • Anonymous
    April 27, 2009
    ">>why not use an interface instead of a the "dynamic" type? Because its easier to write "dynamic", then to implement several interfaces. " The answer runs deeper than that. Imagine you are working on a large enterprise scale project that utilizes a number of third party libraries. Say you have a LibA.dll and LibB.dll. Both these libraries provide charting capabilities. Say LibA has class ClassA and Lib.dll has class ClassB. Depending on the kind of chart you are displaying (bar or pie) your method to render chart takes either LibA.ClassA or LibB.ClassB and calls the .Draw method. With dynamics you can do like this void RenderChart(dynamics x) {  x.Draw(); } Yes the example I have taken can possibly be solved with Generics. But this is just intended to point out that there are conditions that require "duck typing". Basically this is useful in all those situations where members of different types have a common set of members amongst their implemented interfaces even if they don't implement a single common interface.

  • Anonymous
    December 23, 2009
    Is this just a modern version of IDispatch for what we used to call late binding?

  • Anonymous
    January 22, 2010
    Duck Typing is a great concept. For those of us who have experience using static languages there is a slight bit of hesitation about using it at first but when you realize how powerful it is you just can resist it. I wrote a post about Duck Typing a couple of weeks ago if anyone is interested: http://www.codecapers.com/post/Duck-Typing.aspx