The BCL bug of the day

time to read 3 min | 518 words

Now this one if quite an interesting one. Let us take a look and see what happen when we have the following calling code:

public class Program
{
    static void Main()
    {
        dynamic d = new MyDynamicObject();
        Console.WriteLine(d.Item.Key);
    }
}

And the following MyDynamicObject:

public class MyDynamicObject : DynamicObject
{
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = new {Key = 1};
        return true;
    }
}

What do you expect the result of executing this code would be?

If you think that this will print 1 on the console, you are absolutely correct.

Except…

If Program and MyDynamicObject are on separate assemblies.

In that case, we end up with a terribly confusing message:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException was unhandled
  Message='object' does not contain a definition for 'Key'
  Source=Anonymously Hosted DynamicMethods Assembly
  StackTrace:
       at CallSite.Target(Closure , CallSite , Object )
       at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
       at ConsoleApplication1.Program.Main() 
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)

I have been able to narrow this down to “anonymous objects from a different assembly”.

Now that you have the bug, figure out:

  • Why this is happening?
  • How would you work around this bug?
  • How would you reproduce this bug without using anonymous types?
  • How would you fix this bug?
    • What should you be careful when fixing this bug?
  • What would be Microsoft’s response to that?