| 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