Odd behavior of C# 4.0 “dynamic”

Update: Since this behavior hasn’t changed in VS 2010 RC, I have reported the problem to MS on their Connect Site: Dynamic Dispatch in C# doesn’t seem to work in simple case

I’m testing a few things with VS 2010 beta 2, around the “dynamic” keyword in C# 4.0. Mostly good, but there’s a bit of odd behavior — I thought I’d post about it, in case somebody has a comment, and so I don’t forget to test again once I go to the RC again (had it installed the other day, just to find there was no compatible IronPython release and no F# PowerPack either!).

So here’s one thing that’s weird. I have two classes:

public class Leaf {
  public void Fall( ) {
    Console.WriteLine("Leaf is falling");
  }
}

public class ExchangeRate {
  public Action Fall {
    get {
      return ( ) =>
        Console.WriteLine("Exchange rate is falling");
    }
  }
}

I also have this helper function:

static void DoFall(dynamic thing) {
  try {
    thing.Fall( );
  }
  catch {
    Console.WriteLine("Turns out {0} can't fall.", thing);
  }
}

I call the helper function like this:

DoFall(new Leaf( ));
DoFall(new ExchangeRate( ));
DoFall(42);

The result is the obvious one:

Leaf is falling
Exchange rate is falling
Turns out 42 can't fall.

But now I call the helper function like this instead:

var things = new dynamic[] {
  new Leaf(),
  new ExchangeRate(),
  42
};

foreach (dynamic thing in things)
  DoFall(thing);

And suddenly the result changes:

Turns out Basics.Leaf can't fall.
Exchange rate is falling
Turns out 42 can't fall.

Suddenly, the method Leaf.Fall can’t be executed anymore… funny that, I would have thought that would be the more obvious of the two implementations in this example.

I’ve had a similar difference in behavior before, when I was implementing my own DynamicObject. In that case it came down to different optimizations (?), which the C# compiler apparently applies based on how much it knows about the actual object type at the point of invocation. These resulted in two different call patterns for my own type, where TryInvokeMember would be used in some cases and TryGetMember followed by Invoke in others. I can imagine that something similar is behind this case I’m seeing now, but of course there’s not much I can do about it here, since the types in question are just standard C# classes.

Well. I’ll try again with the RC. Meanwhile, if you have any comments, feel free…

3 Comments on Odd behavior of C# 4.0 “dynamic”

  1. I checked this out in the RC and Leaf “falls” correctly both times.

    Like

  2. David,

    That is good to know, thanks for the feedback!

    Like

  3. Well… I just checked it in RC myself, and unfortunately the problem is still there. I’ve extended the sample code to output the exception message, and it says “The name ‘Fall’ is bound to a method and cannot be used like a property”.

    I find that interesting – perhaps this is more closely related to this other issue I described here: http://www.sturmnet.org/blog/2010/02/16/more-odd-behavior-dynamicobject-this-tim , than I previously thought.

    Like

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s