Try fast search NHibernate

03 May 2010

C#4 ‘dynamic’ hole

I’m working in a new .Net4 Cloud project to run in Windows Azure. The proof of concept work fine and now I’m working in the real project writing tests and implementing classes.
I need some classes to initialize the Azure storage based on some conventions, in particular during the implementation of my TableStorageInitializer<TTableEntity> and, overall, its test I found a really nice issue with dynamic.
To simplify the situation a little bit have a look to this simplified implementation:
public class TableStorageInitializer<TTableEntity> where TTableEntity : class, new()
{
public void Initialize()
{
InitializeInstance(new TTableEntity());
}

public void InitializeInstance(dynamic entity)
{
entity.PartitionKey = Guid.NewGuid().ToString();
entity.RowKey = Guid.NewGuid().ToString();
}
}

To test it I’m using a private class declared inside the test class:

private class MyClass
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTime Timestamp { get; set; }
}


With my very big surprise what happen is shown in this picture:


DynamicHole


As you can see dynamic does not work. Even if the debugger can show the right type with its public properties the DLR can’t recognize it.

How solve the situation ? Well… very very easily, old-school Reflection!!!

public void InitializeInstance(object entity)
{
var entityType = entity.GetType();
entityType.GetProperty("PartitionKey").SetValue(entity, Guid.NewGuid().ToString(), null);
entityType.GetProperty("RowKey").SetValue(entity, Guid.NewGuid().ToString(), null);
}

Note: with a public class the dynamic work as expected.

8 comments:

  1. Is select broken... or is this what the C#4 spec says?

    ReplyDelete
  2. If you can find documentation about it let me know. Thanks.

    ReplyDelete
  3. Looks like a bug to me, but you'll probably find it written in some corner of the spec.

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. I don't know if it's a hole but it is a very weird behavior indeed.

    I struggled with this when trying to use dynamic to represent an internal subclass of a public base class from outside its assembly; the exception message was: 'baseclass' does not contain a definition for 'property'

    Note that if you declare MyClass public and try to access a non-existent property the exception message would be:
    'MyClass' does not....
    instead of
    'object' does not....

    It seems that you can't use dynamic to access non-public types/members.

    ReplyDelete
  6. There is a language spec inside VS folder "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC#\Specifications\1033"

    You probably want to have a look at:
    7.2 Static and Dynamic Binding

    ReplyDelete
  7. I posted a question on SO: http://stackoverflow.com/questions/2774554/is-this-a-hole-in-dynamic-binding-in-c-4

    ReplyDelete