2

here a solution is given to get value of a property of a class by supplying its name . now I wonder how I can do the same in this condition :

I have a class MyClass . this class ha a property of type Foo named foo . the Foo has a property of type Bar named bar . and bar has a string property named value .

properties are not static .

I want to be able to get value of foo.bar.value by passing the string "foo.bar.value" as propertyName . in other word I want to pass the property path to get its value .

is it possible ?

Community
  • 1
  • 1
mohsen dorparasti
  • 8,107
  • 7
  • 41
  • 61
  • This is confusing: _"I want to be able to get value of ( Foo.Bar.Value ) value by passing the "Foo.Bar.Value" ."_ – Tim Schmelter Aug 27 '12 at 11:36
  • Can i ask why you want such a thing? That sounds rather weird and prone to errors. – Tim Schmelter Aug 27 '12 at 11:41
  • @TimSchmelter , well the class comes from the client . so the function has no idea what's the structure . so the path must be given too . for some reason's I can't use interface to force a structure – mohsen dorparasti Aug 27 '12 at 11:48
  • What if the class changes in future? Why can't you add a reference to the dll? How do you want to get a property of a class that you cannot access? – Tim Schmelter Aug 27 '12 at 11:50
  • @TimSchmelter ,sorry if my explanation was not clear . the function gets an instance of the user class , aside with path to the property it needs for its operation , through its parameters. – mohsen dorparasti Aug 27 '12 at 11:54

4 Answers4

5

You can do this with a recursive method. Each call takes the value with the first word in path and call the method again with the rest of the part.

public object GetPropertyValue(object o, string path)
{
    var propertyNames = path.Split('.');
    var value = o.GetType().GetProperty(propertyNames[0]).GetValue(o, null);

    if (propertyNames.Length == 1 || value == null)
        return value;
    else
    {
        return GetPropertyValue(value, path.Replace(propertyNames[0] + ".", ""));
    }
}
mohsen dorparasti
  • 8,107
  • 7
  • 41
  • 61
Amiram Korach
  • 13,056
  • 3
  • 28
  • 30
  • It should be noted that this might not work for an empty `path` argument. Also, it relies on the properties never assuming a `null` value. – O. R. Mapper Aug 27 '12 at 12:02
  • @Amiram Korach : thank you , what about the performance . is this approach a good choice ? – mohsen dorparasti Aug 27 '12 at 12:03
  • 1
    Reflection is not so fast, however usually you do other things in the process like getting data from database or from a service which are much slower. You need to measure the time and see. – Amiram Korach Aug 27 '12 at 12:10
  • One other caution - If the property name shows up twice in a path E.G. MyObject.Child.Child both properties will be removed by the path.Replace when it recurses. SubString might be a safer way to go. – bzarah Oct 16 '12 at 12:28
4

This assumes that the properties are named like the classes. i.e. that the property of Type Foo is also named Foo. Without this assumption, the question is lacking some crucial information.

You can use the string.Split method to separate the string foo.bar.value at the dots. You will then have an array with one element per property name.

Iterate over that array and use PropertyInfo.GetValue to retrieve the value of the properties. The value returned in one operation is the instance passed to GetValue in the following iteration.

string props = "foo.bar.value";
object currentObject = // your MyClass instance

string[] propertyChain = props.Split('.');
foreach (string propertyName in propertyChain) {
    if (propertyName == "") {
        break;
    }

    PropertyInfo prop = currentObject.GetType().GetProperty(propertyName);
    currentObject = prop.GetValue(currentObject);
    if (currentObject == null) {
        // somehow handle the situation that one of the properties is null
    }
}

Update: I have added a safeguard to ensure this will work even if props is empty. In that case, currentObject will remain a reference to the original MyClass instance.

O. R. Mapper
  • 20,083
  • 9
  • 69
  • 114
1

As You pointing to answer of the question here , You need to make use of Reglection to achieve same thing.

With help of reflection you can read value of property.

something like this,

// dynamically load assembly from file Test.dll
Assembly testAssembly = Assembly.LoadFile(@"c:\Test.dll");
// get type of class Calculator from just loaded assembly
Type calcType = testAssembly.GetType("Test.Calculator");
// create instance of class Calculator
object calcInstance = Activator.CreateInstance(calcType);
// get info about property: public double Number
PropertyInfo numberPropertyInfo = calcType.GetProperty("Number");
// get value of property: public double Number
double value = (double)numberPropertyInfo.GetValue(calcInstance, null);

you need a put the code in one function and than split string as per you requirement

public object getvalue(string propname)
{
  //above code with return type object 
}
String[] array = string.Split("foo.bar.value");
//call above method to get value of property..

Read for detail : http://www.csharp-examples.net/reflection-examples/

Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
  • This is not an answer. The OP already knew how to read the value of a property. The question is about how to get the value of a property nested in child objects. – O. R. Mapper Aug 27 '12 at 12:04
1

Assuming FOO is static, you can get the class from a string like this:

C# Reflection: How to get class reference from string?

...and then use the rest of the post you've linked to to get the property and value from there:

Get property Value by its stringy name

If FOO isn't static, you'll need to use reflection on the instance (which would negate the requirement to pass in the name of the class as a string, since you can get the class from the instance with GetType()) - remembering that Bar won't have a value in the class unless it is static.

Community
  • 1
  • 1
Jude Fisher
  • 11,138
  • 7
  • 48
  • 91