PostSharp 4.3 / / Post­Sharp Documentation / Standard Patterns / Parent/Child Relationships / Walkthrough: Enumerating Child Objects
Walkthrough: Enumerating Child Objects

After you have declared the structure of your object graph, you will want to make use of it.

Both the ChildAttribute and ParentAttribute can be used to declare parent-child relationships for other patterns such as Undo/Redo (RecordableAttribute) or threading models (ImmutableAttribute, FreezableAttribute, ...).

You can also use the Aggregatable pattern from your own code. The functionalities of this pattern are exposed by the IAggregatable interface, which all aggregatable object automatically implement. This interface allows you to execute a Visitor method against all child objects of a parent.

In the following example, we see how to implement recursive validation for an object model. We will assume that the InvoiceLine and Address line implement an IValidatable interface.

To enumerate all child objects of a parent:

  1. Cast the parent object to the IAggregatable interface.

    C#
                                var
                                 invoice = 
                                new
                                 Invoice();
    IAggregatable aggregatable = (IAggregatable) invoice;
                              
    Note Note

    The IAggregatable interface will be injected into the Invoice class after compilation. Tools that are not aware of PostSharp may incorrectly report that the Invoice class does not implement the IAggregatable interface. Instead of using the cast operator, you can also use the Cast<SourceType, TargetType>(SourceType) method. This method is faster and safer than the cast operator because it is verified and compiled by PostSharp at build time.

    Note Note

    If you are attempting to access IAggregatable members on either AdvisableCollection<T> or AdvisableDictionary<TKey, TValue> you will not be able to use the cast operator or the Cast<SourceType, TargetType>(SourceType) method. Instead, you will have to use the QueryInterface<T>(Object, Boolean) extension method.

  2. Invoke the VisitChildren(ChildVisitor, ChildVisitorOptions, Object) method and pass a delegate to the method to be executed.

    C#
                                var
                                 invoice = 
                                new
                                 Invoice();
    IAggregatable aggregatable = invoice.QueryInterface<IAggregatable>();
                                
    
                                int
                                 errors = 
                                0
                                ;
                                
    
                                bool
                                 isValid = aggregatable.VisitChildren( (child, childInfo) =>
            {
                
                                var
                                 validatable = child 
                                as
                                 IValidatable;
                
                                if
                                 (validatable != 
                                null
                                )
                {
                    
                                if
                                 ( !validatable.Validate() )
                  errors++;
                }
              
                                return
                                 
                                true
                                ;
            });
                              
    Note Note

    The visitor must return a true to continue the enumeration and false to stop the enumeration.

See Also