views:

32

answers:

2

I'd like to implement a method which allows me to access a property of an unknown/anonymous object (-graph) in a late-bound / dynamic way (I don't even know how to correctly call it).

Here's an example of what I'd like to achieve:

// setup an anonymous object
var a = new { B = new { C = new { I = 33 } } };

// now get the value of a.B.C.I in a late-bound way
var i = Get(a, "B.C.I"); 

And here's a simple implementation using "classic" reflection:

public static object Get(object obj, string expression)
{
    foreach (var name in expression.Split('.'))
    {
        var property = obj.GetType().GetProperty(name);
        obj = property.GetValue(obj, null);
    }
    return obj;
}

What other options do I have with C# / .NET 4 to implement something similar as shown above, but maybe simpler, more performant, etc.?

Maybe there are ways to achieve the same thing, which would allow me to specify expression using a lambda expression instead of a string? Would expression trees be helpful in any way (e.g. as shown in this question)?

Update: the object and the expression are passed into my code via a web service call. That's why I used object and string in my Get() method.

+2  A: 

Do you actually only have the expression as a string? Is it known at compile-time, just that the types themselves aren't known (or are hard to express)? If so:

dynamic d = a;
int i = d.B.C.I;

If you really only have it as a string (e.g. as user-entered data) that makes life a lot harder, and none of the C# 4 features really help you. You could potentially evaluate it as an IronPython script or something like that...

EDIT: Okay, after the update it sounds like you're in the latter situation - in which case, I don't know of a nicer way than using reflection. Some of the built-in property binding built for UIs may help, but I don't know of a clean way of accessing it.

Jon Skeet
Sorry, I wasn't clear. I have updated the question.
M4N
+1  A: 

If you want to use C# style, you could use the Mono compiler as a service from your application. I describe how to do this here: http://stackoverflow.com/questions/3407318/mono-compiler-as-a-service-mcs

As an alternative approach, you could use reflection to put all of your object's properties into an ExpandoObject then use it like a dictionary (because ExpandoObject implements IDictionary). Alternatively, you could use JSON.NET and call JObject.FromObject, which will turn a regular object into a JObject which is accessible in a dictionary-like style (and as an added benefit has recursive graph support). Lastly, you could use the same approach to dump your object into a dictionary of dictionaries.

JeffN825