Open sandboxFocusImprove this doc

COM015: Relationship Attribute on the Backing Field of an Automatic Property

Severity Warning
Reported by PostSharp.Patterns.Aggregation
Message The [<Attribute>] attribute applied to the backing field of the automatic property <Property> has no effect, because the relationship of an automatic property is read from the property. Apply the attribute to the property, not to its backing field, or set the <MSBuildProperty> MSBuild property to True to read the annotations of an automatic property and of its backing field as one.

Cause

The AggregatableAttribute aspect reads the relationship of an automatic property from the attributes of the property, and ignores the attributes that the field: target applies to its backing field. PostSharp reports COM015 when one of the relationship attributes, ChildAttribute, ParentAttribute or ReferenceAttribute, is on the backing field and:

  • the property has no relationship attribute, or
  • the property has the same attribute, so the attribute of the field is redundant.

When the property has no attribute and its type requires one, the [Aggregatable] aspect also reports the error COM002, except in a class with a threading model, which reports COM014 for collections only.

<MSBuildProperty> is PostSharpUnifiedAutomaticPropertyAnnotations. Other cases are reported by COM016 (a [field: Reference] on a read-only property), COM017 (another attribute on the property) and COM018 (a property of a string or value type).

In the following example, the Line property has [Child] both on the property and on its backing field.

using System;
using PostSharp;
using PostSharp.Patterns.Model;

namespace Errors.COM015_Error;

[Aggregatable]
public class Order
{
    // The relationship is read from the property, so [field: Child] has no effect.
    [Child] [field: Child] public OrderLine? Line { get; set; }
}

[Aggregatable]
public class OrderLine
{
    public string Product { get; set; } = "Keyboard";
}

public static class Program
{
    public static void Main()
    {
        Order order = new Order { Line = new OrderLine() };

        object? parent = Post.Cast<OrderLine, IAggregatable>( order.Line ).Parent;
        Console.WriteLine( $"The order is the parent of the line: {parent == order}" );
    }
}
warning COM015: COM015_Error.cs(11,46): The [Child] attribute applied to the backing field of the automatic property Errors.COM015_Error.Order.Line has no effect, because the relationship of an automatic property is read from the property. Apply the attribute to the property, not to its backing field, or set the PostSharpUnifiedAutomaticPropertyAnnotations MSBuild property to True to read the annotations of an automatic property and of its backing field as one.

Resolution

  • Apply the attribute to the property rather than to its backing field: remove the field: target.
  • Alternatively, set the PostSharpUnifiedAutomaticPropertyAnnotations MSBuild property to True in the project. PostSharp then reads the attributes of an automatic property and of its backing field as one set.

In the following example, [Child] is on the property only.

using System;
using PostSharp;
using PostSharp.Patterns.Model;

namespace Errors.COM015_Fixed;

[Aggregatable]
public class Order
{
    // The attribute is on the property only.
    [Child] public OrderLine? Line { get; set; }
}

[Aggregatable]
public class OrderLine
{
    public string Product { get; set; } = "Keyboard";
}

public static class Program
{
    public static void Main()
    {
        Order order = new Order { Line = new OrderLine() };

        object? parent = Post.Cast<OrderLine, IAggregatable>( order.Line ).Parent;
        Console.WriteLine( $"The order is the parent of the line: {parent == order}" );
    }
}
The order is the parent of the line: True

See Also

Reference

AggregatableAttribute
ChildAttribute
ReferenceAttribute

Other Resources

Annotating an Object Model for Parent/Child Relationships (Aggregatable)