JakeMangan
JakeMangan

Reputation: 49

Changing the value of each string property in an object

I have an object that contains a number of child objects, with each of the children objects having a varying number of string properties.

I want to write a method that allows me to input a single parent object which will iterate through every string property in each child object and trim the whitespace from the property contents.

For visualisation:

public class Parent
{
    Child1 child1 { get; set;}
    Child2 child2 { get; set;}
    Child3 child3 { get; set;}
}

public class Child1 (Child2 and Child3 classes are similar)
{
    string X { get; set; }
    string Y { get; set; }
    string Z { get; set; }
}

I have the following code, which creates a list of properties in the parent class, then iterates through each of them and finds the child properties which are strings, and then operates on them. But for some reason this does not seem to have any effect on the values of the properties.

private Parent ReduceWhitespaceAndTrimInstruction(Parent p)
{
    var parentProperties = p.GetType().GetProperties();

    foreach(var properties in parentProperties)
    {
        var stringProperties = p.GetType().GetProperties()
            .Where(p => p.PropertyType == typeof(string));

        foreach(var stringProperty in stringProperties)
        {
            string currentValue = (string)stringProperty.GetValue(instruction, null);

            stringProperty.SetValue(p, currentValue.ToString().Trim(), null);
        }
    }
    return instruction;
}

Edit: Forgot to mention. The problem seems to step from the inner foreach, the outer foreach finds each property, but finding the properties that only are strings seems to work incorrectly.

Edit: Updated Method

private Parent ReduceAndTrim(Parent parent)
        {
            var parentProperties = parent.GetType().GetProperties();

            foreach (var property in parentProperties)
            {
                var child = property.GetValue(parent);
                var stringProperties = child.GetType().GetProperties()
                    .Where(x => x.PropertyType == typeof(string));

                foreach (var stringProperty in stringProperties)
                {
                    string currentValue = (string) stringProperty.GetValue(child, null);
                    stringProperty.SetValue(child, currentValue.ToString().Trim(), null);
                }
            }

            return parent;
        }

Upvotes: 0

Views: 656

Answers (2)

IHTS
IHTS

Reputation: 31

The GetProperties method only returns the public properties of your type. If you change the property of your Parent class to the following, you should be able to move forward:

public class Parent
{
    public Child1 Child1 { get; set; }
    public Child2 Child2 { get; set; }
    public Child3 Child3 { get; set; }
}

But this line of code will still return null because there is no property of "parent" in your child classes:

var child = property.GetValue(parent);

I hope it helped :D

Upvotes: 0

dymanoid
dymanoid

Reputation: 15217

Your stringProperties enumerable contains no items, because you're asking the Parent type to give you all properties of type string - there are none.

var stringProperties = p.GetType().GetProperties()
    .Where(p => p.PropertyType == typeof(string));

Note that p is of type Parent, so p.GetType() yields typeof(Parent).

You need to get each property value (each Child instance) of Parent's instance instead:

var parentProperties = p.GetType().GetProperties();

foreach (var property in parentProperties)
{    
    var child = property.GetValue(p);
    var stringProperties = child.GetType().GetProperties()
        .Where(p => p.PropertyType == typeof(string));

    // etc
}

Upvotes: 1

Related Questions