Search code examples
c#reflection.net-2.0

Initializing nested complex types using Reflection


Code tree is like:

Class Data
{
    List<Primitive> obj;
}

Class A: Primitive
{
    ComplexType CTA;
}

Class B: A
{
    ComplexType CTB;
    Z o;
}

Class Z
{
   ComplexType CTZ;
}

Class ComplexType { .... }

Now in List<Primitive> obj, there are many classes in which ComplexType object is 'null'. I just want to initialize this to some value.

The problem is how to traverse the complete tree using reflection.

Edit:

Data data = GetData(); //All members of type ComplexType are null. 
ComplexType complexType = GetComplexType();

I need to initialize all 'ComplexType' members in 'data' to 'complexType'


Solution

  • If I understand you correctly perhaps something like this would do the trick:

    static void AssignAllComplexTypeMembers(object instance, ComplexType value)
    {
         // If instance itself is null it has no members to which we can assign a value
         if (instance != null)
         {
            // Get all fields that are non-static in the instance provided...
            FieldInfo[] fields = instance.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
    
            foreach (FieldInfo field in fields)
            {
               if (field.FieldType == typeof(ComplexType))
               {
                  // If field is of type ComplexType we assign the provided value to it.
                  field.SetValue(instance, value);
               }
               else if (field.FieldType.IsClass)
               {
                  // Otherwise, if the type of the field is a class recursively do this assignment 
                  // on the instance contained in that field. (If null this method will perform no action on it)
                  AssignAllComplexTypeMembers(field.GetValue(instance), value);
               }
            }
         }
      }
    

    And this method would be called like:

    foreach (var instance in data.obj)
            AssignAllComplexTypeMembers(instance, t);
    

    This code only works for fields of course. If you want properties as well you would have to have the loop iterate through all properties (which can be retreived by instance.GetType().GetProperties(...)).

    Be aware though that reflection is not particularly efficient.