views:

454

answers:

2

What is the best way to go about this in C#?

string propPath = "ShippingInfo.Address.Street";

I'll have a property path like the one above read from a mapping file. I need to be able to ask the Order object what the value of the code below will be.

this.ShippingInfo.Address.Street 

Balancing performance with elegance. All object graph relationships should be one-to-one. Part 2: how hard would it be to add in the capability for it to grab the first one if its a List<> or something like it.

+1  A: 

Sounds like a set of nested property invocations:

class X has a property called ShippingInfo; the type represented by ShippingInfo has a property Address; the type represented by Address has a property called Street.

So, assuming that you know the appropriate instance of class X to operate upon:

  • tokenize the string via string.Split( ".".ToCharArray() ) to a string[], or something like that
  • start with the known instance of X
  • use reflection to obtain the MethodInfo for the ShippingInfo getter
  • use reflection to obtain the Type returned by ShippingInfo get()
  • Invoke the getter using reflection
  • using the return value from the ShippingInfo get() and the Type of the return:
    • obtain the MethodInfo for the Address getter in the returned type.....

and so on. You get the picture.

Seems a bit long and tedious, and it is. But that is how you would do it via reflection.

I wonder if it is possible to do the same thing with LINQ to Objects?

The answer to part 2 involves getting the initial value of X from your List<>.

kmontgom
Can you please rewrite this? Not very easy to understand - too many words :)
Nayan
No. If anything, its too brief and short of details. Thats the problem with something like reflection, there are many steps and each step requires specific knowledge. Sorry.
kmontgom
+8  A: 

Perhaps something like this?

string propPath = "ShippingInfo.Address.Street";

object propValue = this;
foreach (string propName in propPath.Split('.'))
{
    PropertyInfo propInfo = propValue.GetType().GetProperty(propName);
    propValue = propInfo.GetValue(propValue, null);
}

Console.WriteLine("The value of " + propPath + " is: " + propValue);

Or, if you prefer LINQ, you could try this instead. (Although I personally prefer the non-LINQ version.)

string propPath = "ShippingInfo.Address.Street";

object propValue = propPath.Split('.').Aggregate(
    (object)this,
    (value, name) => value.GetType().GetProperty(name).GetValue(value, null));

Console.WriteLine("The value of " + propPath + " is: " + propValue);
LukeH
+1 because the code example is shorter than its textual description *g*
Foxfire
I like it. I stand corrected about the difficulties of expressing this. Cool LINQ implementation too.
kmontgom