views:

183

answers:

4

I am having problem getting values of a class whose one property is another class.

Here is an example:

public class Person 
{
    private int age;
    private string name;

    public Person()
    {
        Address = new Address();

    }

    public int Age
    {
        get { return age; }
        set { age = value; }
    }

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public Address Address { get; set; }
}

public class Address
{
    public string street { get; set; }
    public string houseno { get; set; }
}


public class Program
{
    static void Main(string[] args)
    {

        Person person = new Person();
        person.Age = 27;
        person.Name = "Fernando Vezzali";
        person.Address.houseno = "123";
        person.Address.street = "albert street";

        Type type = typeof(Person);

        PropertyInfo[] properties = type.GetProperties();
        foreach (PropertyInfo property in properties)
        {
            Console.WriteLine("{0} = {1}", property.Name, property.GetValue(person, null));

        }
   }
}

But with this I dont get values of address.

Can someone help here?

+2  A: 

type.GetProperties() only gets the properties for that type, one of which is an object Address. street and houseno are not properties on Person.

Console.Write... implicitly calls ToString() on each parameter. So you probably see "Address - Namespace.Address" as an output, because someAddressObject.ToString() will return the type name.

The easiest way to get what you want for this specific situation is to override ToString() on your Address object to output some meaningful string representation of the object:

public override ToString()
{
    return string.Format("#{0} {1}",
        this.houseno,
        this.street); //returns #123 StreetName
}

If you actually need to write every property of every sub-object on your object, that can get fairly complex - you're essentially talking about serialization, which recurses down an object tree and into each object.

Rex M
A: 

Either you need to implement ToString() in Address, if you're happy with returning a formatted string as the value of Address, or your iteration code needs to inspect each property to determine whether that property's type also exposes properties, and enqueue it for further inspection.

JasonTrue
+2  A: 

Here is the possible ToString, taking into account the Jason's answer...

You can also cast your returned reflected objet into an Address to access the full object and properties

public class Address
{
    public string street { get; set; }
    public string houseno { get; set; }
    public override ToString() {
        return string.Format("street: {0}, house: {1}", street, houseno);
    }
}
Jhonny D. Cano -Leftware-
A: 

Your foreach is iterating through all properties properly, and I beleive it is implicitely calling ToString on it to get the value, so override the ToString method of your Address class, and return the properties as a string.

Or, in the foreach, test to see if your property is a value type or a class type by getting the property type and checking IsValueType or IsClass. If IsValueType is false, then iterate through the properties of that properties' class type just as you did for the properties of Person.

Something like this (You may need to tweek to get this to compile, but it gives you the idea):

Person person = new Person();        
person.Age = 27;        
person.Name = "Fernando Vezzali";        
person.Address.houseno = "123";        
person.Address.street = "albert street";        

Type type = person.GetType();        

PropertyInfo[] properties = type.GetProperties();        
foreach (PropertyInfo property in properties)        
{
    //get the type of this property
    Type tyProperty = property.PropertyType;

    object oValue = property.GetValue(person, null));        

    //if the property is a value
    if (tyProperty.IsValueType)
    {
        Console.WriteLine("{0} = {1}", property.Name, oValue);
    }
    else  //else if property type is a class
    {
        oSubValue = property.GetValue(oValue, null)); 

        //loop through the classes properties
        PropertyInfo[] lstSubProperties = tyProperty.GetProperties();        
        foreach (PropertyInfo propSub in lstSubProperties)        
        {
             Console.WriteLine("{0} = {1}", propSub .Name, oSubValue);  
        }
    }
}
Jeremy
Hi Jeremy,Thats what I want to do, but how to do it, thats my questionI can check if its class, but couldnt achieve to get each property of that property (address).
Parminder