Dan Newcome, blog

I'm bringing cyber back

Limitations of C# dynamic

with 5 comments

I’ve been using the new dynamic keyword along with anonymous types recently, but I think that these features kind of miss the mark. Anonymous types aren’t dynamic at all — they just define the type implicitly — you can’t add new items at runtime. However you can use the DLR’s ExpandoObject if you want to be able to add items at runtime. In either case the most serious limitation is that using dynamic doesn’t let you access members that are specified at runtime.

For example, this is not valid:

dynamic obj = GetMyObj();
string field = GetMyField();
object value = obj[ field ];

furthermore, trying to access a member that doesn’t exist throws an exception:

dynamic obj = new { field1 = "foo" };
// throws RuntimeBinderException
string val = obj.field2;

Since we can’t specify fields dynamically at runtime, it is not possible to create some function that will safely access an arbitrary member and return null if it doesn’t exist. In Javascript and other dynamic languages, it is idiomatic to say things like the following:

var foo = obj.field1 || "Default";

We know that accessing field1 will return undefined so we can assign a default value with a simple assertion. At the very least we’d like to be able to do:

object foo = DynamicFieldExists( obj, "field1" ) ? GetValue( obj, "field1" ) : "Default";

However since we can’t access dynamic fields using indexer notation, I don’t know how we would write the DynamicFieldExists and GetValue functions needed to wrap the access up into a try/catch to avoid throwing an exception if the field doesn’t exist. Here is what I’d like to write:

public static bool DynamicFieldExists( dynamic obj, string field ) {
    bool retval = false;        
    try {
        // can't write the following:
        var temp = obj[ field ];
        retval = true;
    }
    catch( RuntimeBinderException ) {}        
    return retval;
}

If anyone has any thoughts on this I’d love to know.

Advertisements

Written by newcome

July 22, 2010 at 10:56 am

Posted in Uncategorized

5 Responses

Subscribe to comments with RSS.

  1. Ok, so I am new to the dynamic types of .NET 4 but I think what you are after is something like this:

      var newObj = obj as IDictionary;
      return newObj.ContainsKey(field);
    

    I am also doing some playing around wrapping the dynamic type with a static type. I have a contract definition that I can limit to ensure I get access to the fields I think I want in the future. It sort of defeats the purpose, however it makes it really easy to parse XML and just use the interface contract on the client side:

    public interface IWrapper
    {
      string Value { get; }
    }
    
    public class Wrapper
    {
      private dynamic instance;
      public Wrapper(dynamic instance)
      {
        this.instance = instance;
      }
    
      public string Value { get {return instance.value;} }
    }
    

    Jono

    August 1, 2010 at 11:01 pm

  2. Yay for stripping of characters. Let’s try a line with encoding!

    var newObj = obj as IDictionary<string, object>;
    

    Jono

    August 1, 2010 at 11:02 pm

  3. And just to complete my spamming comments, one could do this in the get accessors – it’s a little verbose though:

    public string Value 
    { 
      get 
      {
        try
        {
          return instance.value;
        } 
        catch( RuntimeBinderException ex) 
        {
          return String.Empty;
        }
      }
    }
    

    Jono

    August 1, 2010 at 11:14 pm

  4. Thanks for the comments Jono – I added formatting tags so that the WordPress formatter picks things up. I’ll take a look at casting to IDictionary. I suppose that you’d have to implement IDictionary though for each type you’d want to do this with. If you can’t do it with anonymous types though, it wouldn’t be that useful for what I’m trying to do. I’d imagine that you could also create an indexer extension method that would be able to do something similar, where you’d wrap up the cast into an indexer property.

    newcome

    August 2, 2010 at 10:39 am

  5. Ah yeah, I wasn’t sure what the WP tags were for code 😉

    The ExpandoObject implements IDictionary so you can safely cast to it, which is why I use that rather than anonymous types. But I am using it exclusively for reading an XML stream that doesn’t play nicely with the XmlSerializer object.

    Provided I know the format of the response before I create the dynamic object I can define a set of interfaces mapping to the various properties. This could be very useful when implementing the Facebook Api as an owner of a post can be a few different things (person, page, band page [lots of stupid EXTRA fields]) and a post can be different types (link, status, video). So I simply define the interfaces and let Facebook return whichever fields it wants and let my interfaces do all the work.

    Jono

    August 2, 2010 at 3:20 pm


Leave a Reply

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

%d bloggers like this: