| Severity | Error |
| Reported by | PostSharp.Patterns.Common |
| Message | Invalid [Child] custom attribute on <Member>: the value of the IsParentSurrogate property is not valid for the type of this field or property. Remove the IsParentSurrogate property to let PostSharp choose the relationship from the type. |
Cause
A field or property with the ChildAttribute attribute is either a child of the instance or a parent surrogate. A parent surrogate, typically a collection, passes the instance on as the parent of its own items: the items are the children of the instance, not of the collection. The IsParentSurrogate property chooses between the two: true for a parent surrogate, false for a child. When you do not set it, PostSharp chooses from the type of the field or property.
Some types can have only one of the two relationships. For example, an ImmutableArray<T> is a value type, so it cannot be a child, only a parent surrogate. PostSharp reports COM007 when IsParentSurrogate requests a relationship that the type of the field or property cannot have.
In the following example, IsParentSurrogate = false makes the Lines array a child of the invoice, which an ImmutableArray<T> cannot be.
using System;
using System.Collections.Immutable;
using PostSharp;
using PostSharp.Patterns.Model;
namespace Errors.COM007_Error;
[Aggregatable]
public class InvoiceLine
{
public string Product { get; set; } = "";
}
[Aggregatable]
public class Invoice
{
// An ImmutableArray can only be a parent surrogate, but the attribute says it is a child.
[Child( IsParentSurrogate = false )]
public ImmutableArray<InvoiceLine> Lines { get; set; }
}
public static class Program
{
public static void Main()
{
Invoice invoice = new Invoice();
invoice.Lines = ImmutableArray.Create( new InvoiceLine { Product = "Keyboard" }, new InvoiceLine { Product = "Mouse" } );
foreach ( InvoiceLine line in invoice.Lines )
{
object? parent = Post.Cast<InvoiceLine, IAggregatable>( line ).Parent;
Console.WriteLine( $"{line.Product}: parent is the invoice: {parent == invoice}" );
}
}
}
error COM007: COM007_Error.cs(19,40): Invalid [Child] custom attribute on Errors.COM007_Error.Invoice.Lines: the value of the IsParentSurrogate property is not valid for the type of this field or property. Remove the IsParentSurrogate property to let PostSharp choose the relationship from the type.
Resolution
Remove the IsParentSurrogate property from the attribute, so that PostSharp chooses the relationship that the type allows, or set it to the value that the type allows.
In the following example, the array is a parent surrogate, and the invoice lines get the invoice as their parent.
using System;
using System.Collections.Immutable;
using PostSharp;
using PostSharp.Patterns.Model;
namespace Errors.COM007_Fixed;
[Aggregatable]
public class InvoiceLine
{
public string Product { get; set; } = "";
}
[Aggregatable]
public class Invoice
{
// IsParentSurrogate is not set, so PostSharp makes the array a parent surrogate and its items children of the invoice.
[Child]
public ImmutableArray<InvoiceLine> Lines { get; set; }
}
public static class Program
{
public static void Main()
{
Invoice invoice = new Invoice();
invoice.Lines = ImmutableArray.Create( new InvoiceLine { Product = "Keyboard" }, new InvoiceLine { Product = "Mouse" } );
foreach ( InvoiceLine line in invoice.Lines )
{
object? parent = Post.Cast<InvoiceLine, IAggregatable>( line ).Parent;
Console.WriteLine( $"{line.Product}: parent is the invoice: {parent == invoice}" );
}
}
}
Keyboard: parent is the invoice: True
Mouse: parent is the invoice: True
See Also
Reference
ChildAttribute
AggregatableAttribute
Other Resources
Working With Child Collections
Annotating an Object Model for Parent/Child Relationships (Aggregatable)