| Severity | Warning |
| Reported by | PostSharp.Patterns.Aggregation |
| Message | The backing field of the automatic property <Property> is annotated with [<FieldAttribute>] and the property with [<PropertyAttribute>]. The relationship is [<PropertyAttribute>]; the attribute of the backing field does not change it. |
Cause
The AggregatableAttribute aspect reads the relationship of an automatic property from the attributes of the property. PostSharp reports COM017 when the property has one relationship attribute, such as ReferenceAttribute, and the field: target applies another one, such as ChildAttribute, to its backing field. The attribute of the property wins, so the two attributes contradict each other and one of them is not what you meant.
In the following example, the Customer property is a reference, although its backing field has [Child]: the customer gets no parent.
using System;
using PostSharp;
using PostSharp.Patterns.Model;
namespace Errors.COM017_Error;
[Aggregatable]
public class Order
{
// The property says [Reference], so [field: Child] does not make the customer a child.
[Reference] [field: Child] public Customer? Customer { get; set; }
}
[Aggregatable]
public class Customer
{
public string Name { get; set; } = "Alice";
}
public static class Program
{
public static void Main()
{
Order order = new Order { Customer = new Customer() };
object? parent = Post.Cast<Customer, IAggregatable>( order.Customer ).Parent;
Console.WriteLine( $"{order.Customer.Name}, parent of the customer: {parent ?? "none"}" );
}
}
warning COM017: COM017_Error.cs(11,49): The backing field of the automatic property Errors.COM017_Error.Order.Customer is annotated with [Child] and the property with [Reference]. The relationship is [Reference]; the attribute of the backing field does not change it.
Resolution
Decide which relationship the property has, and apply only that attribute, to the property:
- If the attribute of the property is right, remove the attribute of the backing field.
- Otherwise, replace the attribute of the property with the one of the backing field, and remove the
field:attribute.
In the following example, the customer is shared by several orders, so the property keeps [Reference] only.
using System;
using PostSharp;
using PostSharp.Patterns.Model;
namespace Errors.COM017_Fixed;
[Aggregatable]
public class Order
{
// One attribute, on the property, states the relationship.
[Reference] public Customer? Customer { get; set; }
}
[Aggregatable]
public class Customer
{
public string Name { get; set; } = "Alice";
}
public static class Program
{
public static void Main()
{
Order order = new Order { Customer = new Customer() };
object? parent = Post.Cast<Customer, IAggregatable>( order.Customer ).Parent;
Console.WriteLine( $"{order.Customer.Name}, parent of the customer: {parent ?? "none"}" );
}
}
Alice, parent of the customer: none
See Also
Reference
AggregatableAttribute
ChildAttribute
ReferenceAttribute
Other Resources
Annotating an Object Model for Parent/Child Relationships (Aggregatable)