Click here to Skip to main content
15,891,775 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

Consider this scenario:
C#
class A {
      public B {
          get; set;
      }
}

class B {
     public string name { get; set; }
}


Now I want to get a reference to the B object of the A object.

So I am using PropertyInfo Class to get that but through pi = GetValue();
And that I assume doesn't return the reference but a copy of the object since, after setting the value to the object, it doesn't update the original Class A object.

Here is a code snippet that does the work:
C#
      // _TargetObject is the original A object.
private void SyncFieldChanges(string changed_field_id)
{
     PropertyInfo so;
     PropertyInfo to;
     object lv;
     object tw = null;

     try
     {
         to = GetNestedProperty(ref _TargetObject, FindTargetPropertyId(changed_field_id),ref tw);
         so = this.GetType().GetProperty(changed_field_id);

         lv = so.GetValue(this, null);
         to.SetValue(tw, lv, null);
     }
     catch { }

}

PropertyInfo GetNestedProperty(ref object target_object, string nested_property,ref object obj_to_write)
{
     object to;
     string tmp = "";
     string[] np;
     PropertyInfo pi = null;

     obj_to_write = null;

     if(string.IsNullOrEmpty(nested_property)) { return null; }
     np = nested_property.Split('.');
     if (np == null || (np.Length < 2)) 
     {
          pi = target_object.GetType().GetProperty(nested_property);
//This is where the obj_to_write after final recursion is set            
          obj_to_write = target_object;
          return pi;
     }

     for (int i = 1; i < np.Length; i++)
     {
          pi = target_object.GetType().GetProperty(np[i - 1]);

  //CULPRIT - Since in the next recursion call the reference to the to object is passed and to is fetched through GetValue...
          to = pi.GetValue(target_object,null);

          for(int j = i; j < np.Length; j++)
          {
              tmp += np[j] + (j + 1 == np.Length ? "" : ".");
          }
          pi = GetNestedProperty(ref target_object, tmp,ref obj_to_write);
      }
            
   return pi;
}


//--The function returns PropertyInfo object to the nested property, and obj_to_write should be the object just before the farthest nested property, the obj_to_write should point to B object inside A object, and it does that but I think the culprit is above (marked 'CULPRIT' :D) because pi.GetValue returns an object's value not a reference to that object (assumption).
This function is recursive so it might be a little hard to understand...

C#
//--This i just helper function for locating property names  
private string FindTargetPropertyId(string key)
{
     string rv = "";
     KeyValuePair&lt;string, string&gt; kvp;
     kvp = FieldLinks.Find(delegate(KeyValuePair&lt;string, string&gt; o) { return o.Key == key; });
     rv = kvp.Value;
     return rv;
}


Any ideas how to get a reference to an object?
Posted
Updated 4-Jul-10 21:47pm
v2

I've really had a time decoding your code so to speak, are you a c++ developer by any chance?

Anyway, I think your algorithm has run-away with itself. Assuming you pass the property name like this "Property1.SubProperty2.Subproperty3", I think you need something like this:


public object FindValue(object rootObject, string properties)
{
  
  List<string> propertyNames = new List <string>(string.Split("."));
  if(string.Length == 0)
    return null;
  return GetValue(rootObject, propertyNames);

}

public object GetValue(object currentObject, List<string>propertyNames)
{
    if(object == null)
     return null;
    if(propertyNames.Count == 0)
     return currentObject;
    PropertyInfo propertyInfo = currentObject.GetType().GetProperty(propertyNames[0]);
    if(propertyInfo == null)
        return null;
    propertyNames.RemoveAt(0);
    object nextObject= propertyInfo.GetValue(currentObject, null);
    return GetValue(nextObject, propertyNames); 
}


Disclaimer: I haven't tested my code & it's getting late here, this code might not be optimal, I think it makes one more iteration than it strictly needs!
propertyInfo.GetValue(currentObject, null) only works for non-indexed values.
 
Share this answer
 
Comments
tntblow 16-Dec-11 0:52am    
THIS WAS GREAT! Thanks billions for this piece of code man. I was rly lost about storing a referance to an objects Text (or anything) property. Now you rescued me rly. Here is the code to Set a value, of course by coming out from your code (its vb.net anyways but can be easily translated):

Public Sub SetObjectValue(rootObject As Object, properties As String, value As String)
Dim propertyNames As New List(Of String)(properties.Split("."))
If properties.Length = 0 Then
Return
End If
SetValue(rootObject, propertyNames, value)

End Sub
Public Sub SetValue(currentObject As Object, propertyNames As List(Of String), value As String)
If currentObject Is Nothing Then
Return
End If
Dim propertyInfo As Reflection.PropertyInfo = currentObject.[GetType]().GetProperty(propertyNames(0))
If propertyInfo Is Nothing Then
Return
End If
propertyNames.RemoveAt(0)
If propertyNames.Count = 0 Then
propertyInfo.SetValue(currentObject, value, Nothing)
Return
End If
Dim nextObject As Object = propertyInfo.GetValue(currentObject, Nothing)
SetValue(nextObject, propertyNames, value)
End Sub
Thanks Keith,

Well I'm not not a C++ developer (used to be :) developing micro-controller embedded software)

Thank you for your answer although, I have found out the real culprit...

I just didn't see it...

I was passing a structure to my code, and of course structure being a value type is unreflectable in this way...

Actually my code was working from the beginning, just for reference types...

Thanks anyway! :)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900