7

I have a class with over 100 uniquely named properties and more than 20 child-classes, sometimes in lists. Below is a greatly simplified illustration of what I mean:

public class classA
    {
        public String PropertyA1 { get; set; }
        public int PropertyA2{get;set;}
        public List<classB> myList;
        public classC myClass { get; set; }

        public void SetProperty(String PropertyName)
        {
            // Match property name to property in this class or child class.
        }
    }

    class classB
    {
        public String PropertyB1 { get; set; }
        public bool PropertyB2 { get; set; }
    }

    class classC
    {
        public String PropertyC1 { get; set; }
    }

I would like to do two things that may or may not be possible. The first thing I need to do is iterate through every public property, including those of child classes and classes in a list, and translate the values. I know I can accomplish the parsing by serializing to xml and parsing through the results. I even have the code in place to convert to xml, as the function of the class is to build an xml object. However, I am worried that parsing through the xml might be much more expensive than accessing the properties through reflection. Can reflection be used in this manner, and would it be quicker than modifying the xml?

The other thing I would like to do is access any property passing the property name into a method. I realize I would need a separate method for accessing classes within lists, and may have to convert the list to a dictionary. The question is, would this be possible, and would the code only need to be in the parent class, or would each of the child classes need to repeat the code?

8
  • Sounds like you need to look into reflection. Look at Type.GetProperty and Type.GetProperties to start with.
    – Jon Skeet
    Commented Jun 25, 2013 at 19:16
  • 1
    The things you are trying to do are possible through reflection, but we'd like to see what you've learned so far trying to achieve this and where you are stuck Commented Jun 25, 2013 at 19:16
  • The XML Serializer uses reflection to generate the XML document. I think you'll find reflection to be faster
    – Jay
    Commented Jun 25, 2013 at 19:18
  • 3
    "I have a class with over 100 uniquely named properties and more than 20 child-classes". Oh, how I pity you.
    – Euphoric
    Commented Jun 25, 2013 at 19:18
  • 1
    So you have two sets of objects one to consume your source XML the other to serialize to and your mapping from one to the other? Automapper won't work for you?
    – Jay
    Commented Jun 25, 2013 at 19:53

1 Answer 1

12

Method that will set the property with the given name:

    public void SetProperty(String propertyName, object value)
    {
        this.GetType().GetProperty(propertyName).SetValue(this, value);
    }

A few things about the implementation:

  • The type used is the dynamic actual type of the object, that will find members that are in derived classes (as long as the object is of the derived type of course).
  • The property info has no idea of what object it came from, so this must be passed in again to the SetValue() call.

The second part of your question, to iterate through a list of properties, can be solved by using GetProperties() to get all the properties of the object, including inherited ones:

var properties = this.GetType().GetProperties();
6
  • You could make that a generic extension, then you don't have to paste that method in every class hierarchy.
    – Jay
    Commented Jun 25, 2013 at 19:25
  • Thank you Anders, for your response. I believe this would work for the base class, but would I be able to set the value of PropertyC1 calling this method in classA?
    – Tim
    Commented Jun 25, 2013 at 19:26
  • @Jay: The SetProperty method should be a member of the base class. Don't make it an extension - that will make it available to more places. It's ugly, so let's keep it only where it's needed. Commented Jun 25, 2013 at 19:26
  • @Tim: Yes, as long as the object is an instance of ClassC, it will be able to set PropertyC1 even though the method is defined in ClassA because the method uses the objects actual type through this.GetType() rather than the base class type. Commented Jun 25, 2013 at 19:28
  • I still think extensions are better here. Because now all the classes have to inherit from the same base, which may not be desired. You could at least create an interface IPropertySetable and extend that.
    – Jay
    Commented Jun 25, 2013 at 19:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.