Open sandboxFocusImprove this doc

DOM007: Property Depends on Too Many Fields of Its Type

Severity Warning
Reported by PostSharp.Patterns.Model
Message Property <Property> depends on more than five fields whose type is compatible with the type of the property, which makes tracking the changes of its value less efficient. To avoid this warning, split the property into several properties that each depend on fewer fields.

Cause

The NotifyPropertyChangedAttribute aspect binds each property to the fields that its getter reads and whose type is assignable to the type of the property: any of these fields can hold the object that the property returns. The aspect uses these bindings to notify the property when a property of the returned object changes. Each time the property is read, the aspect compares its value with every bound field to find which one holds it.

PostSharp warns with DOM007 when a property is bound to more than five fields, typically when the getter returns the first of several fields that is set. <Property> is the name of the property, without the name of its class. PostSharp reports the message on the property.

The warning is about performance: the property is still notified correctly.

In the following example, the DisplayName property of Contact can return any of six fields of type string.

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

namespace Errors.DOM007_Error;

[NotifyPropertyChanged]
public class Contact
{
    private string? nickname, firstName, lastName, company, email, phone;

    // The getter can return the value of six fields of type string.
    public string DisplayName => this.nickname ?? this.firstName ?? this.lastName ?? this.company ?? this.email ?? this.phone ?? "(unknown)";

    public void Update( string? nickname, string? firstName, string? lastName, string? company, string? email, string? phone )
    {
        this.nickname = nickname;
        this.firstName = firstName;
        this.lastName = lastName;
        this.company = company;
        this.email = email;
        this.phone = phone;
    }
}

public static class Program
{
    public static void Main()
    {
        Contact contact = new();
        ((INotifyPropertyChanged) contact).PropertyChanged += ( _, e ) => Console.WriteLine( $"PropertyChanged: {e.PropertyName}" );

        contact.Update( null, null, null, "Contoso", "info@contoso.com", null );
        Console.WriteLine( $"DisplayName: {contact.DisplayName}" );
    }
}
warning DOM007: DOM007_Error.cs(13,19): Property DisplayName depends on more than five fields whose type is compatible with the type of the property, which makes tracking the changes of its value less efficient. To avoid this warning, split the property into several properties that each depend on fewer fields.
PropertyChanged: DisplayName
DisplayName: Contoso

Resolution

Split the property into several properties that each read at most five of the fields, and make the original property depend on these properties. Alternatively, ignore the warning when the property does not change often.

In the following example, DisplayName depends on the PersonalName and BusinessName properties, which read three fields each.

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

namespace Errors.DOM007_Fixed;

[NotifyPropertyChanged]
public class Contact
{
    private string? nickname, firstName, lastName, company, email, phone;

    public string? PersonalName => this.nickname ?? this.firstName ?? this.lastName;

    public string? BusinessName => this.company ?? this.email ?? this.phone;

    // The getter depends on two properties, each of which depends on three fields.
    public string DisplayName => this.PersonalName ?? this.BusinessName ?? "(unknown)";

    public void Update( string? nickname, string? firstName, string? lastName, string? company, string? email, string? phone )
    {
        this.nickname = nickname;
        this.firstName = firstName;
        this.lastName = lastName;
        this.company = company;
        this.email = email;
        this.phone = phone;
    }
}

public static class Program
{
    public static void Main()
    {
        Contact contact = new();
        ((INotifyPropertyChanged) contact).PropertyChanged += ( _, e ) => Console.WriteLine( $"PropertyChanged: {e.PropertyName}" );

        contact.Update( null, null, null, "Contoso", "info@contoso.com", null );
        Console.WriteLine( $"DisplayName: {contact.DisplayName}" );
    }
}
PropertyChanged: BusinessName
PropertyChanged: DisplayName
DisplayName: Contoso

See Also

Reference

NotifyPropertyChangedAttribute

Other Resources

Understanding the NotifyPropertyChanged Aspect
Implementing INotifyPropertyChanged with Properties that Depend on Other Objects